【问题标题】:How to call Grandchild in Wagtail如何在鹡鸰中称呼孙子
【发布时间】:2018-07-29 08:59:46
【问题描述】:

我正在为 Django 使用 Wagtail,并想在模板中调用孙子,但不知道该怎么做。我是新手,似乎在 wagtail 文档中找不到任何内容。我看到了页面查询参考文档here,但不知道如何应用它。

我的Django项目树如下:

project/
    home/
        models.py
            > class HomePage
    news/
        models.py
            > class NewsPostPage
            > class NewsIndexPage

在主页模板中,我想将来自新闻应用的最新新闻插入到模板中。

home/models.py

from django.db import models
from django.utils.translation import ugettext_lazy as _

from modelcluster.models import ParentalKey

from wagtail.admin.edit_handlers import FieldPanel
from wagtail.core.models import Page

from news.models import NewsIndexPage

class HomePage(Page):
    why_choose_us_title_en = models.CharField(
        verbose_name=_('[EN] Why Choose Us Title'),
        max_length=200,
        default='',
        blank=True,
    )

    why_choose_us_subtitle_en = models.CharField(
        verbose_name=_('[EN]Why Choose Us Subtitle'),
        max_length=200,
        default='',
        blank=True,
    )

    content_panels = Page.content_panels + [
        FieldPanel('why_choose_us_title_en', classname='full title'),
        FieldPanel('why_choose_us_subtitle_en'),
    ]

    subpage_types = [
        'news.NewsIndexPage',
    ]

    @property
    def featured_products(self):
        return ProductPage.objects.filter(featured=True)

    news_index = NewsIndexPage

news/models.py

from datetime import timedelta

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone

from wagtail.admin.edit_handlers import FieldPanel, RichTextFieldPanel
from wagtail.core.fields import RichTextField
from wagtail.core.models import Page
from wagtail.images.edit_handlers import ImageChooserPanel

from base.models import TranslatedField


class NewsPostPage(Page):
    news_title_en = models.CharField(
        max_length=7250,
        verbose_name=_('[EN] News Post Page Title'),
        blank=True,
        default='',
    )
    news_text_en = RichTextField(
        verbose_name=_('[EN] News Text'),
        blank=True,
        default='',
        help_text=_('[EN] News content')
    )
    preview_text_en = RichTextField(
        verbose_name=_('[EN] News Preview Text'),
        blank=True,
        default='',
        help_text=_('[EN] Index Page News Preview Text')
    )
    created = models.DateField(
        verbose_name=_('Release Date'),
        blank=True
    )

    @property
    def recent_posts(self):
        two_months_before = timezone.now().date() - timedelta(days=60)
        posts = NewsPostPage.objects.filter(created__gt=two_months_before)
        return posts

    content_panels = Page.content_panels + [
        FieldPanel('news_title_en', classname='title full'),
        RichTextFieldPanel('news_text_en'),
        RichTextFieldPanel('preview_text_en'),
        FieldPanel('created')
    ]

    parent_page_types = ['NewsIndexPage']


class NewsIndexPage(Page):
    news_index_title_en = models.CharField(
        max_length=250,
        verbose_name=_('[EN] News Index Title'),
        blank=True,
        default='',
    )
    news_index_image = models.ForeignKey(
        'wagtailimages.Image',
        related_name='+',
        null=True,
        on_delete=models.SET_NULL
    )

    content_panels = Page.content_panels + [
        FieldPanel('news_index_title_en'),
        ImageChooserPanel('news_index_image'),
    ]

    subpage_types = ['NewsPostPage']

    @property
    def news_posts(self):
        return self.get_children().live().specific()

    @property
    def recent_posts(self):
        two_months_before = timezone.now().date() - timedelta(days=60)
        posts = NewsPostPage.objects.filter(created__gt=two_months_before)
        return posts

主页/模板

{% block content %}
<div id="kotak-news-events" class="kotak-grid">
     <h4 class="title-strip title-kotak-bawah">Recent News and Events</h4>
     <table>
         {% for post in page.news_index.news_posts.all %}
             <tr>
                 <td>{{ post.created }}</td>
                 <td>{{ post.translated_preview_text|richtext }}</td>
             </tr>
         {% endfor %}
    </table>
</div>

{% endblock %}

我不知道如何在 NewsPostPage 中插入项目以使其显示在主页模板中。提前致谢

【问题讨论】:

  • 主页上有featured_products 方法。在模板中,您可以执行 {% for obj in page.featured_products %}{{ obj }}{% endfor %} 之类的操作。你为什么不对新闻做类似的事情?
  • 您的问题的标题具有误导性。也许将其更改为“如何在家中显示新闻?”。您的对象在页面树中的位置与您的问题无关。
  • 是的。你说的对。我重用了我的旧代码并忘记了它。谢谢

标签: python html django wagtail


【解决方案1】:

您要做的是向您的模板添加额外的context。 Wagtail 具有将视图和模型混合在一起的酷炫功能。因此,您所要做的就是将您的@properties 添加到您发送到模板的context。像这样:

class NewsIndexPage(Page):

    template = 'templates/news_index_page.html'

    @property
    def news_posts(self):
        return self.get_children().live()

    @property
    def recent_posts(self):
        two_months_before = timezone.now().date() - timedelta(days=60)
        posts = NewsPostPage.objects.filter(created__gt=two_months_before)
        return posts

    def get_context(self, request, *args, **kwargs):
        """Add posts to context"""
        context = super().get_context(request)
        context['recent_posts'] = self.recent_posts
        context['news_posts'] = self.news_posts
        return context

因为您将 QuerySet 返回到模板,所以您可以正常循环它们。所以你的模板看起来像这样:

{% block content %}
<div id="kotak-news-events" class="kotak-grid">
     <h4 class="title-strip title-kotak-bawah">Recent News and Events</h4>
     <table>
         {% for post in news_posts %} {# Notice the loop here #}
             <tr>
                 <td>{{ post.created }}</td>
                 <td>{{ post.translated_preview_text|richtext }}</td>
             </tr>
         {% endfor %}
    </table>
</div>
{% endblock %}

【讨论】:

  • 问题是我想使用家庭应用程序调用 news_posts,但我似乎无法访问 NewsIndexPage 中的 news_post
【解决方案2】:

原来你只需要添加一个属性,我通过添加自定义属性来解决,如下所示:

class HomePage(Page):
    why_choose_us_title_en = models.CharField(
        verbose_name=_('[EN] Why Choose Us Title'),
        max_length=200,
        default='',
        blank=True,
    )

    why_choose_us_subtitle_en = models.CharField(
        verbose_name=_('[EN]Why Choose Us Subtitle'),
        max_length=200,
        default='',
        blank=True,
    )

    content_panels = Page.content_panels + [
        FieldPanel('why_choose_us_title_en', classname='full title'),
        FieldPanel('why_choose_us_subtitle_en'),
    ]

    subpage_types = [
        'news.NewsIndexPage',
    ]

    @property
    def featured_products(self):
        return ProductPage.objects.filter(featured=True)

    # removed this line
    # news_index = NewsIndexPage

    # added this code
    @property
    def news_index(self):
        return NewsPostPage.objects.live()

并且仍然在 HTML 中使用它

{% block content %}
<div id="kotak-news-events" class="kotak-grid">
     <h4 class="title-strip title-kotak-bawah">Recent News and Events</h4>
     <table>
         {% for post in page.news_index.all %}
             <tr>
                 <td>{{ post.created }}</td>
                 <td>{{ post.translated_preview_text|richtext }}</td>
             </tr>
         {% endfor %}
    </table>
</div>

{% endblock %}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    相关资源
    最近更新 更多