Я использую django-taggit для управления своим тегом. Я хочу включить список используемых тегов с указанием того, сколько раз использовался каждый из них. Для этого я использую taggit_templatetags2, но я могу этого избежать.
My models.py
:
from taggit.managers import TaggableManager
class Post(models.Model):
...
tags = TaggableManager(blank=True)
My template.html
:
{% load taggit_templatetags2_tags %}
{% get_taglist as tags for 'blog.post' %}
{% for tag in tags %}
{% if tag.slug != 'draft' and tag.slug != 'retired' %}
<h4 style="text-align:center"><a href="{% url 'blog:post_list_by_tag' tag.slug %}">
{{ tag }} ({{ tag.num_times }}) </a></h4>
{% endif %}
{% endfor %}
Но я хочу исключить из подсчета все теги черновых сообщений и удаленных сообщений. Я хочу исключить не только теги «черновик» и «пенсионер» (я уже делаю это), но и другие теги, которые могут быть у таких постов. Как я могу это сделать?
Например, у меня есть два поста. У первого есть только тег «собака». Второй имеет теги «собака» и «черновик». Это черновик, пост еще не опубликован.
Мой код дал бы: собака (2), потому что он подсчитывает теги всех сообщений. Когда пользователь нажмет на «собаку», появится страница со всеми опубликованными сообщениями с тегом собаки, поэтому в нашем случае это одно сообщение, потому что второе не опубликовано. Пользователь спросит себя: там два собачьих поста, а где второй? Это нехорошо. Также я не хочу намекать на аргументацию постов, которые скоро будут опубликованы.
Вероятно, мне придется возиться с кодом taggit_templatetags2
...
Честно говоря, мне трудно понять этот код, также я думаю, что было бы лучше не изменять непосредственно исходный код, иначе при первом обновлении мой код будет потерян.
Вот код taggit_templatetags2
:
@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 ''
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))
куда:
queryset = manager.all()
дает список всех тегов
count_field
это строка: taggit_taggeditem_items
queryset.annotate(num_times=Count(count_field))
— набор запросов с дополнительным полем num_times
,