【问题标题】:Django MultiWidget and field labelsDjango MultiWidget 和字段标签
【发布时间】:2020-02-02 17:16:05
【问题描述】:

我需要一个包含 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,感觉有点hacky:

<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 %}
...

但是,对于一般的表单元素,标签被分配给 字段,但如果我定义它们,我无法找到小部件从 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)

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

【问题讨论】:

  • 这正是我当前的问题(除了我的字段是动态创建的,因此我无法使用“长格式”选项)。你有没有达到满意的解决方案?我正处于完全放弃MultiWidget 的边缘。
  • @simon 我最终切换到 vue 作为前端并使用 django 作为 api 层
  • 是的,我可以在这个项目的未来看到这种可能性......谢谢!

标签: python django django-forms


【解决方案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)

结果如下:

【讨论】:

    猜你喜欢
    • 2010-12-19
    • 2012-04-18
    • 2012-10-22
    • 2012-06-07
    • 2017-03-21
    • 2023-04-05
    • 2014-12-07
    • 2011-05-15
    • 2012-04-19
    相关资源
    最近更新 更多