0

我有一个 wagtail 管理表单,我想在其中自定义用于填充 ManyToMany 字段的一系列复选框选项的布局。我正在编辑的模型称为“产品”;该字段是“displays_on_pages”,它链接到一个单独的“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)和标签(标题),但我似乎无法使用“特定”来获取其他“页面”模型属性,例如“路径”或“深度”。尝试在模板中输出类似 {{ 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_page_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 %}

在“product_page_div”内部,我想根据页面深度做一些有条件的事情,我需要弄清楚如何引用它(或如何重新定义传入的查询集以使其包含该信息) .

以下是包含的模板“forms/product_page_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 %}

和“表单/product_page_input.html”:

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

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

4

0 回答 0