3

我们有一个博客模型的设置,该模型与 BlogPageCategory 具有多对多关系,并且我们有一个“最近的博客文章”流域块,可让您指定是否显示 X 最新博客文章或来自特定类别的 X 最新博客文章的卡片.

因此,我们从以下代码开始:

from wagtail.core import blocks


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=[
            ('all', 'All'),
            ('First Category', 'First Category'),
            ('...',. '...'),
        ],
    )

    ...

但是对类别进行硬编码有点愚蠢,并且能够从“现在基于 BlogPageCategory 的 CMS 数据的列表是什么”中选择它们会方便得多。但是,以下代码(当然)变成了同样硬编码的迁移:

from wagtail.core import blocks
from ... import BlogPageCategory


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    choices = [ (cat.name, cat.name) for cat in BlogPageCategory.objects.all()]
    choices.sort()
    choices.insert(0, ('all', 'All'))

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=choices,
    )

    ...

有没有办法让它成为一个动态值而不是一个由 固定的列表makemigrations

4

1 回答 1

8

ChoiceBlock接受一个可调用函数作为choices参数:

def get_categories():
    return [(cat.name, cat.name) for cat in BlogPageCategory.objects.all()]


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=get_categories,
    )

可调用对象需要在模块的顶层定义,以便迁移可以引用它(即它不能是类上的方法),如果它随后被移动或重命名,您将需要相应地编辑迁移。

于 2020-04-01T19:43:13.540 回答