Django MultiWidget 和字段标签

Mat*_*vor 5 python django django-forms

我需要一个 Django 表单,其中包含 3 个forms.Textarea被压缩为单个models.TextField兼容值的表单。为此,我对forms.MultiValueField和进行了子类化forms.MultiWidget。我的问题是尝试确定在何处以及如何向小部件的textarea输入添加标签。

我当前正在做的是将标签值作为attr小部件的子小部件传递:

class ContentWidget(forms.MultiWidget):
    template_name = 'content_widget.html'

    def __init__(self, attrs=None):
        widgets = (
            forms.Textarea({'label': 'A'}),
            forms.Textarea({'label': 'B'}),
            forms.Textarea({'label': 'C'}),
        )
        super().__init__(widgets, attrs)
Run Code Online (Sandbox Code Playgroud)

这让我保持content_widget.html相当简洁:

{% for subwidget in widget.subwidgets %}
  <label for="{{ subwidget.attrs.id }}">{{ subwidget.attrs.label }}</label>
  {% include subwidget.template_name with widget=subwidget %}
  <br />
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

但这也label为每个 html 元素添加了 attr,这感觉有点 hacky:

{% for subwidget in widget.subwidgets %}
  <label for="{{ subwidget.attrs.id }}">{{ subwidget.attrs.label }}</label>
  {% include subwidget.template_name with widget=subwidget %}
  <br />
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

另一种选择是将其显式包含在模板的更长版本中:

<label for="{{ widget.subwidgets.0.attrs.id }}">A</label>
{% include widget.subwidgets.0.template_name with widget=subwidget %}
...
Run Code Online (Sandbox Code Playgroud)

但是,对于一般的表单元素,标签被分配给 field MultiValueField但是如果我在那里定义它们,我找不到小部件从实例访问它们的方法:

<textarea name="content_0" cols="40" rows="10" label="A" required="" id="id_content_0"></textarea>
Run Code Online (Sandbox Code Playgroud)

我担心的是,这会使代码更难维护,而且这表明我在这里错过了一些明显的东西。我的问题是是否有更一致的方法。

小智 3

我发现做类似事情的唯一方法是添加占位符属性

class TimedeltaWidget(forms.MultiWidget):
    def __init__(self, fields, attrs=None, *args, **kwargs):
        fields[0].widget.attrs={'placeholder': _('Days')}
        fields[1].widget.attrs={'placeholder': _('Hours')}
        fields[2].widget.attrs={'placeholder': _('Minutes')}
        fields[3].widget.attrs={'placeholder': _('Seconds')}
        widgets = (fields[0].widget, fields[1].widget, fields[2].widget, fields[3].widget, )
        super(TimedeltaWidget, self).__init__(widgets, attrs)
Run Code Online (Sandbox Code Playgroud)

结果如下:

结果图像