Wagtail,如何从不同的模型填充 ChoiceBlock 中的选项?

Wagtail, how do I populate the choices in a ChoiceBlock from a different model?

这是显示在文本顶部的图标模型,它们有名称和图标。

from django.db import models
from django.utils.translation import ugettext as _
from django.conf import settings


class SomeSortOfIcon(models.Model):

    name = models.CharField(max_length=200,
                            verbose_name=_('Icon Name'),
                            help_text=_('This value will be shown to the user.'))

    image = models.ForeignKey(
        getattr(settings, 'WAGTAILIMAGES_IMAGE_MODEL', 'wagtailimages.Image'),
        on_delete=models.PROTECT,
        related_name='+',
        verbose_name=_('Icon'),
    )

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Icon')
        verbose_name_plural = _('Icons')

这是要添加到页面流场中的块的代码。

from django.db import models
from django import forms
from django.utils.translation import ugettext as _

from wagtail.wagtailcore import blocks

from xxx.models import SomeSortOfIcon


class SomeSortOfIconChooserBlock(blocks.ChoiceBlock):
    ## PROBLEM HERE, where do I get the choices from?
    choices = tuple([(element.name, element.image) for element in SomeSortOfIcon.objects.all()])
    target_model = SomeSortOfIcon


class SomeBox(blocks.StructBlock):

    headline = blocks.TextBlock(required=True)

    some_icon = SomeSortOfIconChooserBlock(label='Icon', required=True)

    info_box_content = blocks.RichTextBlock(label='Content', required=True)

    class Meta:
        template = 'blocks/some_box.html'
        icon = 'form'
        label = _('Some Box')

所以,我确实将 Block 添加到流场中,对于图标,我想要一个下拉菜单,其中包含来自图标模型的选项。它应该显示名称,当您选择一个名称时,它将按名称自动添加到 html.

我得到了下拉菜单,但它是空的。我尝试使用 choices 属性,但我不知道如何将它连接到其他模型。

有人可以帮忙吗?非常感谢。

您可以通过继承 ChooserBlock 来做到这一点。

class SomeSortOfIconChooserBlock(blocks.ChooserBlock):
    target_model = SomeSortOfIcon
    widget = forms.Select

    class Meta:
        icon = "icon"

    # Return the key value for the select field
    def value_for_form(self, value):
        if isinstance(value, self.target_model):
            return value.pk
        else:
            return value

并在您的区块中使用

class SomeBox(blocks.StructBlock):
    headline = blocks.TextBlock(required=True)
    some_icon = SomeSortOfIconChooserBlock(required=True)
    info_box_content = blocks.RichTextBlock(label='Content', required=True)

    class Meta:
        template = 'blocks/some_box.html'
        icon = 'form'
        label = _('Some Box')

这将根据 SomeSortOfIcon 模型的对象为您提供下拉菜单。