如何设置 InlinePanel 中初始空(可订购)项目的数量?

How can I set the number of initial empty (orderable) items in an InlinePanel?

我有一个名为 SetListItemOrderable 模型,在一个名为 FloorWithSetsClusterableModel 上有一个 ParentalKey。父 FloorWithSets 模型定义使用 InlinePanel 来控制 SetListItem 的 adding/ordering/removing。我遇到的问题是,管理表单会自动为每个 FloorWithSets 呈现三个空的 SetListItem,我找不到任何方法来控制此设置。

InlinePanel class 需要 parameters 例如设置项目的最小和最大数量,但不设置呈现的初始空项目的数量。

我在 Wagtail 文档中找不到任何关于此的信息。我还为 InlinePanelEditHandler 挖掘了 source 但找不到任何我可以覆盖的东西。

我确实从 InlinePanel template file 中看到有一个 ID 结尾为 -INITIAL_FORMS 的隐藏输入,它正在通过 self.formset.management_form 呈现。该字段的值始终低于 id 结尾为 -TOTAL_FORMS 的相邻隐藏输入,这是有道理的。我只是不明白价值从何而来或如何控制它。

关于这个 INITIAL_FORMS 我能找到的唯一信息似乎都与测试有关,(例如 this documentation),我看不出如何将这些内容与我需要的内容联系起来。

class FloorWithSets(ClusterableModel):
    page = ParentalKey(EventPage, on_delete=models.CASCADE, related_name='floor_with_sets')

    FLOOR_CHOICES = [
        ('1', 'X'),
        ('2', 'Y'),
        ('3', 'Z'),
    ]
    floor = models.CharField(
        max_length=1,
        choices=FLOOR_CHOICES,
        default='1',
    )

    panels = [
        FieldPanel('floor'),
        InlinePanel('set_list', label=_("set")),
    ]


class SetListItem(Orderable):
    floor = ParentalKey(FloorWithSets, on_delete=models.CASCADE, related_name='set_list')

    artist = models.CharField(max_length=255, blank=True, verbose_name=_('artist'))
    label = models.CharField(max_length=255, blank=True, verbose_name=_('label'))
    start_time = models.TimeField(blank=True, null=True, verbose_name=_('start time'))
    end_time = models.TimeField(blank=True, null=True, verbose_name=_('end time'))

    set_list_item = FieldRowPanel([
        FieldPanel('artist', classname="col6"),
        FieldPanel('label', classname="col6")
    ])

    set_list_item_details = FieldRowPanel([
        FieldPanel('start_time', classname="col6"),
        FieldPanel('end_time', classname="col6")
    ])

    panels = [set_list_item, set_list_item_details]

我想我找到了解决办法。尝试使用自定义元 class 为您的 EventPage 模型创建自定义 Form class,如下所示:

class EventPageFormMetaclass(WagtailAdminModelFormMetaclass):
    @classmethod
    def child_form(cls):
        return EventPageForm


class EventPageForm(WagtailAdminPageForm, metaclass=EventPageFormMetaclass):
    pass


class EventPage(Page):
    # Whatever you have in your model

    base_form_class = EventPageForm

我认为问题源于 ClusterFormMetaclasshard-coded 来为子模型创建 ClusterForm 的实例。因此,您的 EventPage 获得 WagtailAdminPageForm,但 FloorWithSets 模型获得 ClusterForm。如果你停在那里,没问题,但是当 FloorWithSets 生成 它是 内联面板时,它作为 ClusterForm 这样做,其元 class 有 extra_form_count 设置为 3,而 WagtailAdminPageForm 的 metaclass 设置为 0.

所以上面的解决方案创建了一个新的 Form class,其 metaclass 将 child_form class 方法覆盖为 return Form class extra_form_count 设置为 0。

呼。