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

时间:2016-08-02 13:42:09

标签: python django wagtail

这是显示在文本顶部的图标模型,它们会得到一个名称和图标。

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添加到了streamfield中,对于图标,我想要一个带有图标模型选项的下拉菜单。它应该显示名称,当你选择一个名称时,它将自动按名称添加到html中。

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

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

1 个答案:

答案 0 :(得分:5)

您可以通过继承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模型的对象为您提供下拉列表。