与 Wordpress 对 post 和 page 做区分不同,wagtail 视一切为页面。比如一个新闻频道,所有的新闻都是索引页的子页面,它们与关于我们类似的单页面性质完全相同,可能最大的区别就是它们属于不同的父页面。

例如有这样一个索引模型:

class NewsIndexPage(Page):
    # 允许创建子页面类型
    subpage_types = ['news.NewsPage']

    banner = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )

    content_panels = Page.content_panels + [
        ImageChooserPanel('banner'),
    ]

如果不做任何设置,在模板中可以通过 page.get_children 调用子页面列表:

{% for post in page.get_children.specific %}
<div>
    <a href="{% pageurl post %}" class="uk-link-reset">
        <div class="uk-card uk-card-default uk-responsive-width">
            <div class="uk-card-media-top">
                {% image post.title_pic original as img  %}
                <img data-src="{{ img.url }}" alt="" uk-img>
            </div>
            <div class="uk-card-body">
                <h3 class="uk-card-title">{{ post.title }}</h3>
                <p>发布日期:{{ post.first_published_at | date:'Y-m-d' }}</p>
            </div>
        </div>
    </a>
</div>
{% endfor %}

如果要让新闻列表只显示正式发布的内容(非草稿),且按从新到旧的顺序排列,可以通过编写 get_context() 方法将符合规则的内容传入页面语境(上下文)中:

class NewsIndexPage(Page):
    ...
    # 按日期降序排列新闻
        def get_context(self, request):
            context = super().get_context(request)
            news_list = self.get_children().live().order_by('-first_published_at')
            context['news_list'] = news_list
            return context

这样一来,就可以直接在模板中从 news_list 迭代新闻列表了:

{% for post in news_list.specific %}
<div>
    <a href="{% pageurl post %}" class="uk-link-reset">
        <div class="uk-card uk-card-default uk-responsive-width">
            <div class="uk-card-media-top">
                {% image post.title_pic original as img  %}
                <img data-src="{{ img.url }}" alt="" uk-img>
            </div>
            <div class="uk-card-body">
                <h3 class="uk-card-title">{{ post.title }}</h3>
                <p>发布日期:{{ post.first_published_at | date:'Y-m-d' }}</p>
            </div>
        </div>
    </a>
</div>
{% endfor %}

排序依据

news_list = self.get_children().live().order_by('-first_published_at')

order_by 中的 first_published_at 是 page 模型的数据库字段,查看所有字段