123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- from classytags.arguments import Argument
- from classytags.core import Options
- from classytags.helpers import AsTag
- from django import template
- from django.contrib.contenttypes.models import ContentType
- from django.core.exceptions import FieldError
- from django.db.models import Count
-
- from taggit_templatetags2 import settings
- from taggit_templatetags2.compat import get_model
-
-
- T_MAX = getattr(settings, 'TAGCLOUD_MAX', 6.0)
- T_MIN = getattr(settings, 'TAGCLOUD_MIN', 1.0)
-
- register = template.Library()
-
-
- def get_queryset(forvar, taggeditem_model, tag_model):
- through_opts = taggeditem_model._meta
- count_field = (
- "%s_%s_items" % (
- through_opts.app_label,
- through_opts.object_name)).lower()
-
- if forvar is None:
- # get all tags
- queryset = tag_model.objects.all()
- else:
- # extract app label and model name
- beginning, applabel, model = None, None, None
- try:
- beginning, applabel, model = forvar.rsplit('.', 2)
- except ValueError:
- try:
- applabel, model = forvar.rsplit('.', 1)
- except ValueError:
- applabel = forvar
- applabel = applabel.lower()
-
- # filter tagged items
- if model is None:
- # Get tags for a whole app
- queryset = taggeditem_model.objects.filter(
- content_type__app_label=applabel)
- tag_ids = queryset.values_list('tag_id', flat=True)
- queryset = tag_model.objects.filter(id__in=tag_ids)
- else:
- # Get tags for a model
- model = model.lower()
- if ":" in model:
- model, manager_attr = model.split(":", 1)
- else:
- manager_attr = "tags"
- model_class = get_model(applabel, model)
- if not model_class:
- raise Exception(
- 'Not found such a model "%s" in the application "%s"' %
- (model, applabel))
- manager = getattr(model_class, manager_attr)
- queryset = manager.all()
- through_opts = manager.through._meta
- count_field = ("%s_%s_items" % (through_opts.app_label,
- through_opts.object_name)).lower()
-
- if count_field is None:
- # Retain compatibility with older versions of Django taggit
- # a version check (for example taggit.VERSION <= (0,8,0)) does NOT
- # work because of the version (0,8,0) of the current dev version of
- # django-taggit
- try:
- return queryset.annotate(
- num_times=Count(settings.TAG_FIELD_RELATED_NAME))
- except FieldError:
- return queryset.annotate(
- num_times=Count('taggit_taggeditem_items'))
- else:
- return queryset.annotate(num_times=Count(count_field))
-
-
- def get_weight_fun(t_min, t_max, f_min, f_max):
- def weight_fun(f_i, t_min=t_min, t_max=t_max, f_min=f_min, f_max=f_max):
- # Prevent a division by zero here, found to occur under some
- # pathological but nevertheless actually occurring circumstances.
- if f_max == f_min:
- mult_fac = 1.0
- else:
- mult_fac = float(t_max - t_min) / float(f_max - f_min)
- return t_max - (f_max - f_i) * mult_fac
- return weight_fun
-
-
- @register.tag
- class GetTagForObject(AsTag):
-
- name = 'get_tags_for_object'
-
- options = Options(
- Argument('source_object', resolve=True, required=True),
- 'as',
- Argument('varname', resolve=False, required=False),
- )
-
- def get_value(self, context, source_object, varname=''):
- """
- Args:
- source_object - <django model object>
-
- Return:
- queryset tags
- """
-
- tag_model = settings.TAG_MODEL
- app_label = source_object._meta.app_label
-
- try:
- model = source_object._meta.model_name
- except AttributeError:
- model = source_object._meta.module_name.lower()
-
- content_type = ContentType.objects.get(app_label=app_label,
- model=model)
-
- try:
- tags = tag_model.objects.filter(
- taggit_taggeditem_items__object_id=source_object,
- taggit_taggeditem_items__content_type=content_type)
- except:
- tags = tag_model.objects.filter(
- taggit_taggeditem_items__object_id=source_object.pk,
- taggit_taggeditem_items__content_type=content_type)
-
- if varname:
- context[varname]
- return ''
- else:
- return tags
-
-
- class TaggitBaseTag(AsTag):
-
- options = Options(
- 'as',
- Argument('varname', resolve=False, required=False),
- 'for',
- Argument('forvar', required=False),
- 'limit',
- Argument('limit', required=False, default=5, resolve=True),
- )
-
-
- @register.tag
- class GetTagList(TaggitBaseTag):
- name = 'get_taglist'
-
- def get_value(self, context, varname, forvar, limit=settings.LIMIT, order_by=settings.TAG_LIST_ORDER_BY):
- # TODO: remove default value for limit, report a bug in the application
- # django-classy-tags, the default value does not work
- queryset = get_queryset(
- forvar,
- settings.TAGGED_ITEM_MODEL,
- settings.TAG_MODEL)
- queryset = queryset.order_by(order_by)
- context[varname] = queryset
- if limit:
- queryset = queryset[:limit]
- return ''
-
-
- @register.tag
- class GetTagCloud(TaggitBaseTag):
- name = 'get_tagcloud'
-
- def get_value(self, context, varname, forvar, limit=settings.LIMIT, order_by=settings.TAG_CLOUD_ORDER_BY):
- queryset = get_queryset(
- forvar,
- settings.TAGGED_ITEM_MODEL,
- settings.TAG_MODEL)
- num_times = queryset.values_list('num_times', flat=True)
- if(len(num_times) == 0):
- context[varname] = queryset
- return ''
- weight_fun = get_weight_fun(
- T_MIN, T_MAX, min(num_times), max(num_times))
- queryset = queryset.order_by(order_by)
- if limit:
- queryset = queryset[:limit]
- for tag in queryset:
- tag.weight = weight_fun(tag.num_times)
- context[varname] = queryset
- return ''
-
-
- @register.inclusion_tag('taggit_templatetags2/tagcloud_include.html')
- def include_tagcloud(forvar=None):
- return {'forvar': forvar}
-
-
- @register.inclusion_tag('taggit_templatetags2/taglist_include.html')
- def include_taglist(forvar=None):
- return {'forvar': forvar}
-
-
- @register.inclusion_tag('taggit_templatetags2/tagcanvas_include.html')
- def include_tagcanvas(element_id, width, height, url_name='tagcanvas-list',
- forvar=None, limit=3):
- """
- Args:
- element_id - str - html id
- width - int - pixels width
- height - int - pixels height
- url_name - if url_name=='' then no links. Default: tagcanvas-list
- """
-
- if url_name == 'default':
- url_name = 'tagcanvas-list'
-
- return {
- 'forvar': forvar,
- 'element_id': element_id,
- 'width': width,
- 'height': height,
- 'url_name': url_name,
- 'limit': limit}
|