Django/Wagtail/taggit — получение списка тегов для конкретной модели

Я видел это:

Создание уникального списка тегов Django-Taggit в трясогузке;

и решения там создали список всех сохраненных тегов, т. е. тегов изображений, документов и т. д.

Я пытаюсь достичь аналогичной цели. На странице индекса новостей есть раскрывающийся список тегов страницы новостей.

Кажется, я не могу получить список тегов, которые являются только тегами страницы новостей, в настоящее время это дает мне список всех тегов на моем сайте, включая теги изображений и документов.

from django.template.response import TemplateResponse
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from modelcluster.tags import ClusterTaggableManager
from taggit.models import TaggedItemBase, Tag
from core.models import Page

class NewsPageTag(TaggedItemBase):
    content_object = ParentalKey('NewsPage', related_name='tagged_items')


class NewsPage(Page):
    tags = ClusterTaggableManager(through=NewsPageTag, blank=True)


class NewsIndexPage(Page):

    def serve(self, request, *args, **kwargs):
        context['tags'] = Tag.objects.all().distinct('taggit_taggeditem_items__tag')
        return TemplateResponse(
            request,
            self.get_template(request, *args, **kwargs),
            context
        )

Я также пробовал:

from django.contrib.contenttypes.models import ContentType
# ...
def serve(self, request, *args, **kwargs):
    news_content_type = ContentType.objects.get_for_model(NewsPage)
    context['tags'] = Tag.objects.filter(
        taggit_taggeditem_items__content_type=news_content_type
    )
    return TemplateResponse(
        request,
        self.get_template(request, *args, **kwargs),
        context
    )

который присваивает context['tags'] пустой набор

Мой шаблон:

{% if tags.all.count %}
    {% for tag in tags.all %}
        <a class="dropdown-item" href="?tag={{ tag.id }}">{{ tag }}</a>
    {% endfor %}
{% endif %}

ПОМОЩЬ! Такое ощущение, что это не должно быть так сложно. Спасибо


person JVsquad    schedule 17.11.2017    source источник


Ответы (1)


Вы можете скопировать, как это достигается, в новом демонстрационном приложении Wagtail Bakery, которое является отличным справочником.

По сути, просто получить все дочерние страницы, а затем получить их теги, используя set, чтобы убедиться, что они являются уникальными объектами.

Сначала добавьте в свой NewsIndexPage метод, который поможет вам получать эти теги согласованным образом.

См.: models.py

class NewsIndexPage(Page):

    # Returns the list of Tags for all child posts of this BlogPage.
    def get_child_tags(self):
        tags = []
        news_pages = NewsPage.objects.live().descendant_of(self);
        for page in news_pages:
            # Not tags.append() because we don't want a list of lists
            tags += page.get_tags
        tags = sorted(set(tags))
        return tags

Поскольку у вас есть метод в вашей модели NewsPageIndex, вам не нужно переопределять метод serve, вы можете получить теги непосредственно в своем шаблоне, как это.

    {% if page.get_child_tags %}
        {% for tag in page.get_child_tags %}
            <a class="dropdown-item" href="?tag={{ tag.id }}">{{ tag }}</a>
        {% endfor %}
    {% endif %}

См. аналогичный подход к шаблону в blog_index_page.html

Примечание. Вы все еще можете добавить контекст, выполнив что-то вроде этого в методе serve:

context['tags'] = self.get_child_tags()
person LB Ben Johnston    schedule 18.11.2017
comment
Спасибо! Это отлично сработало, и демонстрация пекарни Wagtail Bakery очень полезна. - person JVsquad; 20.11.2017