对于任何错误,我深表歉意,英语不是我的母语。
我正在制作包含多个组织的新闻和事件的网站(每个组织都有自己的帐户,允许他们自己创建新闻和事件)。
以新闻为例:
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>
<!-- ... -->
如果有任何帮助和提示,我将不胜感激!
不要尝试过滤模板内的查询 - 在页面模型上的
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 %}