如何设置 InlinePanel 中初始空(可订购)项目的数量?
How can I set the number of initial empty (orderable) items in an InlinePanel?
我有一个名为 SetListItem
的 Orderable
模型,在一个名为 FloorWithSets
的 ClusterableModel
上有一个 ParentalKey
。父 FloorWithSets
模型定义使用 InlinePanel
来控制 SetListItem
的 adding/ordering/removing。我遇到的问题是,管理表单会自动为每个 FloorWithSets
呈现三个空的 SetListItem
,我找不到任何方法来控制此设置。
InlinePanel
class 需要 parameters 例如设置项目的最小和最大数量,但不设置呈现的初始空项目的数量。
我在 Wagtail 文档中找不到任何关于此的信息。我还为 InlinePanel
和 EditHandler
挖掘了 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
我认为问题源于 ClusterFormMetaclass
是 hard-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。
呼。
我有一个名为 SetListItem
的 Orderable
模型,在一个名为 FloorWithSets
的 ClusterableModel
上有一个 ParentalKey
。父 FloorWithSets
模型定义使用 InlinePanel
来控制 SetListItem
的 adding/ordering/removing。我遇到的问题是,管理表单会自动为每个 FloorWithSets
呈现三个空的 SetListItem
,我找不到任何方法来控制此设置。
InlinePanel
class 需要 parameters 例如设置项目的最小和最大数量,但不设置呈现的初始空项目的数量。
我在 Wagtail 文档中找不到任何关于此的信息。我还为 InlinePanel
和 EditHandler
挖掘了 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
我认为问题源于 ClusterFormMetaclass
是 hard-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。
呼。