Django MultiWidget和字段标签

时间:2019-10-04 11:04:17

标签: python django django-forms

我需要一个包含3个forms.Textarea的Django表单,这些表单被压缩为单个models.TextField兼容值。为此,我将forms.MultiValueFieldforms.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)

这使我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 %}

但这还会在每个html元素中添加label attr,这有点让人讨厌:

<textarea name="content_0" cols="40" rows="10" label="A" required="" id="id_content_0"></textarea>

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

<label for="{{ widget.subwidgets.0.attrs.id }}">A</label>
{% include widget.subwidgets.0.template_name with widget=subwidget %}
...

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

class ContentField(forms.MultiValueField):
    def __init__(self, **kwargs):
        fields = (
            forms.CharField(label="A"),
            forms.CharField(label="B"),
            forms.CharField(label="C"),
        )
        super().__init__(fields, require_all_fields=False, **kwargs)

我担心的是这既使代码难以维护,又表明我错过了一些显而易见的内容。我的问题是是否有更一致的方法。

1 个答案:

答案 0 :(得分:1)

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

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)

结果在这里:

image of result