Wagtail:当通过外键访问索引页时,如何过滤索引页的子级

问题描述 投票:0回答:1

对于任何错误,我深表歉意,英语不是我的母语。

我正在制作包含多个组织的新闻和事件的网站(每个组织都有自己的帐户,允许他们自己创建新闻和事件)。

以新闻为例:

NewsIndexPage
是所有
NewsArticlePage
的父级。 每个
NewsArticlePage
都与组织相关。

在 url

/news/
NewsIndexPage
显示所有新闻,并允许使用
RoutablePageMixin
(
/news/organization/<str: organization_slug>/
) 按组织过滤新闻。

此外,每个组织都有自己的登陆页面 (

OrganizationPage
),其中包含组织的信息和新闻部分。 新闻部分最多显示 3 条组织的最新新闻(如在 bakerydemo 存储库中,当最新 3 条博客条目列在
HomePage
中时:

每个

OrganizationPage
都引用
NewsIndexPage
ForeignKey

但我不知道,当通过

NewsIndexPage
访问时,如何过滤
ForeignKey
的子级。

当我访问

OrganizationPage
实例时,我想将组织的 slug 传递给链接的
NewsIndexPage
,以便我可以过滤子
NewsArticlesPage

我唯一想到的就是创建 template_tag ,它将 slug 作为参数传递给某种

get_news_articles(self, organization_slug)
函数。但我还没能做到。

新闻.模型

class NewsArticlePage(Page):
    """
    A news article page.
    """
    image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text=_("Landscape mode only; horizontal width between 1000px and 3000px."),
    )
    body = StreamField(
        BaseStreamBlock(), verbose_name=_("News article page body"), blank=True, use_json_field=True
    )
    date_published = models.DateField(_("Date article published"), blank=True, null=True)
    organization = models.ForeignKey(
        to = Organization,
        on_delete = models.SET_NULL,
        related_name = "news_articles",
        blank=True,
        null=True,
    )

    content_panels = Page.content_panels + [
        FieldPanel("introduction"),
        FieldPanel("image"),
        FieldPanel("body"),
        FieldPanel("date_published"),
    ]
    private_panels = [
        FieldPanel("organization"),
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading=_("Details")),
        ObjectList(private_panels, heading=_("Admin only"), permission="superuser"),
    ])

    search_fields = Page.search_fields + [
        index.SearchField("body"),
    ]

    # Specifies parent to NewsArticlePage as being NewsIndexPages
    parent_page_types = ["NewsIndexPage"]

    # Specifies what content types can exist as children of NewsArticlePage.
    # Empty list means that no child content types are allowed.
    subpage_types = []

    base_form_class = NewsArticlePageForm

    class Meta:
        verbose_name = _("News article page")
        verbose_name_plural = _("News article pages")


class NewsIndexPage(RoutablePageMixin, Page):
    """
    Index page for news.
    """

    introduction = models.TextField(help_text=_("Text to describe the page"), blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("introduction"),
    ]

    def get_context(self, request):
        context = super(NewsIndexPage, self).get_context(request)
        context["news_articles"] = (
            NewsArticlePage.objects.live().order_by("-date_published")
        )
        return context

    def children(self):
        return self.get_children().specific().live()
    
    @route(r"^organization/$", name="news_of_organization")
    @path("organization/<str:organization_slug>/", name="news_of_organization")
    def news_of_organization(self, request, organization_slug=None):
        """
        View function for the organization's news page
        """
        try:
            organization = Organization.objects.get(slug=organization_slug)
        except Organization.DoesNotExist:
            if organization:
                msg = "There are no news articles from organization {}".format(organization.get_shorten_name())
                messages.add_message(request, messages.INFO, msg)
            return redirect(self.url)
        
        news_articles = NewsArticlePage.objects.live().filter(organization__slug=organization_slug).order_by("-date_published")

        return self.render(request, context_overrides={
            'title': _("News"),
            'news_articles': news_articles,
        })


    def serve_preview(self, request, mode_name):
        # Needed for previews to work
        return self.serve(request)
    

    subpage_types = ["NewsArticlePage"]


    class Meta:
        verbose_name = _("News index page")
        verbose_name_plural = _("News index pages")

组织。型号

class Organization(index.Indexed, models.Model):
    # ...
    name = models.CharField(max_length=255)
    # ...
    slug = models.SlugField(
        verbose_name=_("Slug Name"),
        max_length=255,
        unique=True,
        blank=True,
        null=False,
    )
    # ...


class OrganizationPage(Page):
    """
    An organization page.
    """
    organization = models.OneToOneField(
        to=Organization,
        on_delete=models.SET_NULL,
        related_name="organization_page",
        verbose_name=_("Organization"),
        null=True,
        blank=True,
    )

    # Featured sections on the HomePage
    # News section
    news_section_title = models.CharField(
        blank=True, max_length=255, help_text=_("Title to display")
    )
    news_section = models.ForeignKey(
        "news.NewsIndexPage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text=_(
            "News section. Will display up to three latest news articles."
        ),
        verbose_name=_("News section"),
    )

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel("news_section_title"),
                FieldPanel("news_section"),
            ],
            heading=_("News section"),
        ),
    ]

    private_panels = [
        FieldPanel("organization"),
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading=_("Details")),
        ObjectList(Page.promote_panels, heading=_("Promote")),
        ObjectList(private_panels, heading=_("Admin only"), permission="superuser"),
    ])

    # Specifies parent to OrganizationPage as being OrganizationsIndexPage
    parent_page_types = ["OrganizationsIndexPage"]

    # Specifies what content types can exist as children of OrganizationPage.
    # subpage_types = ["news.NewsIndexPage"]
    subpage_types = []

    class Meta:
        verbose_name = _("Organization page")
        verbose_name_plural = _("Organization pages")

模板/组织/组织/organization_page.html

<!-- ... -->
<div class="container">
        <div class="row">
            <div class="news-articles-list">
                {% if page.news_section %}
                    <h2 class="featured-cards__title">{{ page.news_section_title }}</h2>
                    <div class="row">
                        {% for news_article in page.news_section.children|slice:"3" %}
                            {% include "includes/card/news-listing-card.html" with news_article=news_article %}
                        {% endfor %}
                    </div>
                    <a class="featured-cards__link" href="/news/organization/{{ page.slug }}">
                        <span>View more of our news</span>
                    </a>      
                {% endif %}
            </div>
        </div>
    </div>
<!-- ... -->

如果有任何帮助和提示,我将不胜感激!

python django wagtail
1个回答
0
投票

不要尝试过滤模板内的查询 - 在页面模型上的

get_context
方法中进行操作:

class OrganizationPage(Page):
    # ...
    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['news_articles'] = NewsArticlePage.objects.child_of(self.news_section).filter(organization=self.organization).live()[:3]
        return context

这将使变量

news_articles
在模板上可用,您可以对其进行循环:

{% for news_article in news_articles %}
    {% include "includes/card/news-listing-card.html" with news_article=news_article %}
{% endfor %}
© www.soinside.com 2019 - 2024. All rights reserved.