Python Wagtail管理员:如何自定义选择/复选框选项的布局?

Python Wagtail管理员:如何自定义选择/复选框选项的布局?,python,django,wagtail,wagtail-admin,Python,Django,Wagtail,Wagtail Admin,我有一个wagtail管理表单,我想自定义一系列用于填充多个字段的复选框选项的布局。我正在编辑的模型叫做“产品”;该字段为“在页面上显示”,链接到单独的“GenericPage”模型。问题是,我有很多这样的页面作为选项,这使得将它们显示为常规的复选框列表有点不方便。我想显示嵌套的子页面,这样我就可以缩进父页面下的子页面。大概是这样的: □ Parent Page 1 □ Subpage 1.1 □ Subpage 1.1.1 □ Subpage 1.2 □ Parent Page

我有一个wagtail管理表单,我想自定义一系列用于填充多个字段的复选框选项的布局。我正在编辑的模型叫做“产品”;该字段为“在页面上显示”,链接到单独的“GenericPage”模型。问题是,我有很多这样的页面作为选项,这使得将它们显示为常规的复选框列表有点不方便。我想显示嵌套的子页面,这样我就可以缩进父页面下的子页面。大概是这样的:

□ Parent Page 1
  □ Subpage 1.1
    □ Subpage 1.1.1
  □ Subpage 1.2
□ Parent Page 2
  □ Subpage 2.1
(etc.)
我已经了解了如何通过对forms.widgets.CheckboxSelectMultiple子类化来创建自定义表单小部件,如何传入自己的查询逻辑以使作为复选框小部件选项的页面显示为按树排序,以及如何为输出设置模板。问题是,我传递到模板中的选择似乎不是实际的“页面”对象。当我循环查询集时,我可以获得每个选项的值(id)和标签(title),但我似乎无法使用“specific”来获取其他“Page”模型属性,例如“path”或“depth”。试图在模板中输出类似{{option.specific.depth}}的内容,结果是空的。我想做的是在那里抛出一些CSS,根据每个选项的深度来识别一定数量的选项,例如style=“padding left:20px;”如果深度为2,style=“padding left:40px;”如果深度为3,等等

以下是models.py中的相关类:

class ProductPageSelectInput(forms.widgets.CheckboxSelectMultiple):
  template_name = 'forms/product_page_select.html'
  def get_context(self, name, value, attrs):
    context = super(ProductPageSelectInput, self).get_context(name, value, attrs)
    return context

#custom field panel to allow selection of pages to list products on
class ProductPageSelectPanel(FieldPanel):
  
  def on_form_bound(self):
    choices = self.model.get_page_choices(self.model)
    self.form.fields['displays_on_pages'].queryset = choices
    self.form.fields['displays_on_pages'].empty_label = None
    super().on_form_bound()

class Product(Page):
  product_description = RichTextField(features=RICH_TEXT_FIELD_FEATURES,null=True,blank=True)
  displays_on_pages = ParentalManyToManyField('GenericPage', blank=True)
  
  def get_page_choices(self):
    return GenericPage.objects.live()
  
  content_panels = [
    FieldPanel('title'),
    FieldPanel('product_description'),
    ProductPageSelectPanel('displays_on_pages',widget=ProductPageSelectInput),
  ]
下面是模板“forms/product\u page\u select.html”中的内容:

  <div{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>
    {% for group, options, index in widget.optgroups %}
      {% if group %}{{ group }}<div{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}
      {% for option in options %}
        <div id="product_page_div">{% include 'forms/product_page_option.html' with widget=option %}</div>
      {% endfor %}
      {% if group %}</div>{% endif %}
    {% endfor %}
  </div>
{% endwith %}

{widget.optgroups%中的组、选项和索引为%
{%if-group%}{{group}{%endif%}
{options%%中的选项为%s}
{%include'forms/product_page_option.html'和widget=option%}
{%endfor%}
{%if组%}{%endif%}
{%endfor%}
{%endwith%}
在“product_page_div”中,我想根据页面深度有条件地做一些事情,我需要找出引用它的正确方法(或者如何重新定义传入的查询集,以便它包含这些信息)

以下是包含的模板“forms/product\u page\u option.html”的内容:

{% if widget.wrap_label %}<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>{% endif %}{% include "forms/product_page_input.html" %}{% if widget.wrap_label %} {{ widget.label }}</label>{% endif %}
{%if widget.wrap_label%}{%endif%}{%include“forms/product_page_input.html”}{%if widget.wrap_label%}{{{widget.label}{%endif%}
和“表单/产品页面输入.html”:


(后两个基本上是从Wagtail核心的管理模板复制和粘贴的。)

<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>