Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

taggit_templatetags2_tags.py 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. from classytags.arguments import Argument
  2. from classytags.core import Options
  3. from classytags.helpers import AsTag
  4. from django import template
  5. from django.contrib.contenttypes.models import ContentType
  6. from django.core.exceptions import FieldError
  7. from django.db.models import Count
  8. from taggit_templatetags2 import settings
  9. from taggit_templatetags2.compat import get_model
  10. T_MAX = getattr(settings, 'TAGCLOUD_MAX', 6.0)
  11. T_MIN = getattr(settings, 'TAGCLOUD_MIN', 1.0)
  12. register = template.Library()
  13. def get_queryset(forvar, taggeditem_model, tag_model):
  14. through_opts = taggeditem_model._meta
  15. count_field = (
  16. "%s_%s_items" % (
  17. through_opts.app_label,
  18. through_opts.object_name)).lower()
  19. if forvar is None:
  20. # get all tags
  21. queryset = tag_model.objects.all()
  22. else:
  23. # extract app label and model name
  24. beginning, applabel, model = None, None, None
  25. try:
  26. beginning, applabel, model = forvar.rsplit('.', 2)
  27. except ValueError:
  28. try:
  29. applabel, model = forvar.rsplit('.', 1)
  30. except ValueError:
  31. applabel = forvar
  32. applabel = applabel.lower()
  33. # filter tagged items
  34. if model is None:
  35. # Get tags for a whole app
  36. queryset = taggeditem_model.objects.filter(
  37. content_type__app_label=applabel)
  38. tag_ids = queryset.values_list('tag_id', flat=True)
  39. queryset = tag_model.objects.filter(id__in=tag_ids)
  40. else:
  41. # Get tags for a model
  42. model = model.lower()
  43. if ":" in model:
  44. model, manager_attr = model.split(":", 1)
  45. else:
  46. manager_attr = "tags"
  47. model_class = get_model(applabel, model)
  48. if not model_class:
  49. raise Exception(
  50. 'Not found such a model "%s" in the application "%s"' %
  51. (model, applabel))
  52. manager = getattr(model_class, manager_attr)
  53. queryset = manager.all()
  54. through_opts = manager.through._meta
  55. count_field = ("%s_%s_items" % (through_opts.app_label,
  56. through_opts.object_name)).lower()
  57. if count_field is None:
  58. # Retain compatibility with older versions of Django taggit
  59. # a version check (for example taggit.VERSION <= (0,8,0)) does NOT
  60. # work because of the version (0,8,0) of the current dev version of
  61. # django-taggit
  62. try:
  63. return queryset.annotate(
  64. num_times=Count(settings.TAG_FIELD_RELATED_NAME))
  65. except FieldError:
  66. return queryset.annotate(
  67. num_times=Count('taggit_taggeditem_items'))
  68. else:
  69. return queryset.annotate(num_times=Count(count_field))
  70. def get_weight_fun(t_min, t_max, f_min, f_max):
  71. def weight_fun(f_i, t_min=t_min, t_max=t_max, f_min=f_min, f_max=f_max):
  72. # Prevent a division by zero here, found to occur under some
  73. # pathological but nevertheless actually occurring circumstances.
  74. if f_max == f_min:
  75. mult_fac = 1.0
  76. else:
  77. mult_fac = float(t_max - t_min) / float(f_max - f_min)
  78. return t_max - (f_max - f_i) * mult_fac
  79. return weight_fun
  80. @register.tag
  81. class GetTagForObject(AsTag):
  82. name = 'get_tags_for_object'
  83. options = Options(
  84. Argument('source_object', resolve=True, required=True),
  85. 'as',
  86. Argument('varname', resolve=False, required=False),
  87. )
  88. def get_value(self, context, source_object, varname=''):
  89. """
  90. Args:
  91. source_object - <django model object>
  92. Return:
  93. queryset tags
  94. """
  95. tag_model = settings.TAG_MODEL
  96. app_label = source_object._meta.app_label
  97. try:
  98. model = source_object._meta.model_name
  99. except AttributeError:
  100. model = source_object._meta.module_name.lower()
  101. content_type = ContentType.objects.get(app_label=app_label,
  102. model=model)
  103. try:
  104. tags = tag_model.objects.filter(
  105. taggit_taggeditem_items__object_id=source_object,
  106. taggit_taggeditem_items__content_type=content_type)
  107. except:
  108. tags = tag_model.objects.filter(
  109. taggit_taggeditem_items__object_id=source_object.pk,
  110. taggit_taggeditem_items__content_type=content_type)
  111. if varname:
  112. context[varname]
  113. return ''
  114. else:
  115. return tags
  116. class TaggitBaseTag(AsTag):
  117. options = Options(
  118. 'as',
  119. Argument('varname', resolve=False, required=False),
  120. 'for',
  121. Argument('forvar', required=False),
  122. 'limit',
  123. Argument('limit', required=False, default=5, resolve=True),
  124. )
  125. @register.tag
  126. class GetTagList(TaggitBaseTag):
  127. name = 'get_taglist'
  128. def get_value(self, context, varname, forvar, limit=settings.LIMIT, order_by=settings.TAG_LIST_ORDER_BY):
  129. # TODO: remove default value for limit, report a bug in the application
  130. # django-classy-tags, the default value does not work
  131. queryset = get_queryset(
  132. forvar,
  133. settings.TAGGED_ITEM_MODEL,
  134. settings.TAG_MODEL)
  135. queryset = queryset.order_by(order_by)
  136. context[varname] = queryset
  137. if limit:
  138. queryset = queryset[:limit]
  139. return ''
  140. @register.tag
  141. class GetTagCloud(TaggitBaseTag):
  142. name = 'get_tagcloud'
  143. def get_value(self, context, varname, forvar, limit=settings.LIMIT, order_by=settings.TAG_CLOUD_ORDER_BY):
  144. queryset = get_queryset(
  145. forvar,
  146. settings.TAGGED_ITEM_MODEL,
  147. settings.TAG_MODEL)
  148. num_times = queryset.values_list('num_times', flat=True)
  149. if(len(num_times) == 0):
  150. context[varname] = queryset
  151. return ''
  152. weight_fun = get_weight_fun(
  153. T_MIN, T_MAX, min(num_times), max(num_times))
  154. queryset = queryset.order_by(order_by)
  155. if limit:
  156. queryset = queryset[:limit]
  157. for tag in queryset:
  158. tag.weight = weight_fun(tag.num_times)
  159. context[varname] = queryset
  160. return ''
  161. @register.inclusion_tag('taggit_templatetags2/tagcloud_include.html')
  162. def include_tagcloud(forvar=None):
  163. return {'forvar': forvar}
  164. @register.inclusion_tag('taggit_templatetags2/taglist_include.html')
  165. def include_taglist(forvar=None):
  166. return {'forvar': forvar}
  167. @register.inclusion_tag('taggit_templatetags2/tagcanvas_include.html')
  168. def include_tagcanvas(element_id, width, height, url_name='tagcanvas-list',
  169. forvar=None, limit=3):
  170. """
  171. Args:
  172. element_id - str - html id
  173. width - int - pixels width
  174. height - int - pixels height
  175. url_name - if url_name=='' then no links. Default: tagcanvas-list
  176. """
  177. if url_name == 'default':
  178. url_name = 'tagcanvas-list'
  179. return {
  180. 'forvar': forvar,
  181. 'element_id': element_id,
  182. 'width': width,
  183. 'height': height,
  184. 'url_name': url_name,
  185. 'limit': limit}