如何让Django表单显示html必需属性?

Dan*_*ore 16 html forms django html5

我有这个表单字段:

email = forms.EmailField(
  required=True,
  max_length=100,
)
Run Code Online (Sandbox Code Playgroud)

它具有必需的属性,但在html中它没有添加html属性required.事实上,它甚至没有使用email作为字段类型,它正在使用text...虽然看起来得到max_length就好了.

实际:

<input id="id_email" type="text" name="email" maxlength="100">
Run Code Online (Sandbox Code Playgroud)

预期:

<input id="id_email" type="email" name="email" maxlength="100" required="true">
Run Code Online (Sandbox Code Playgroud)

如何让Django在html表单中使用正确的属性?

Luk*_*ger 17

Django表单元素是<input />在HTML 4中存在的,因为它type="text"是电子邮件地址的正确选项.也没有required="true".

如果您想要自定义HTML属性,则需要窗口小部件attrs关键字参数.它看起来像这样:

email = forms.EmailField(
    max_length=100,
    required=True,
    widget=forms.TextInput(attrs={ 'required': 'true' }),
)
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看有关小部件的更多文档.讨论attrs就在该页面的底部附近.

关于type="email",您可以将它发送到您的attrs字典,Django将智能地覆盖其默认值.如果这不是您得到的结果,那么您的路由是子类forms.TextInput,然后将其传递给widget关键字参数.


Jil*_*loc 9

结合Daniel和Daniel的答案,我通常将这个mixin用于我的表单:

from django.contrib.admin.widgets import AdminFileWidget
from django.forms.widgets import HiddenInput, FileInput


class HTML5RequiredMixin(object):

    def __init__(self, *args, **kwargs):
        super(HTML5RequiredMixin, self).__init__(*args, **kwargs)
        for field in self.fields:
            if (self.fields[field].required and
               type(self.fields[field].widget) not in
                    (AdminFileWidget, HiddenInput, FileInput) and 
               '__prefix__' not in self.fields[field].widget.attrs):

                    self.fields[field].widget.attrs['required'] = 'required'
                    if self.fields[field].label:
                        self.fields[field].label += ' *'
Run Code Online (Sandbox Code Playgroud)

因此,当我必须创建一个新的表单或模型时,我只需使用:

class NewForm(HTML5RequiredMixin, forms.Form):
    ...
Run Code Online (Sandbox Code Playgroud)


Dan*_*ore 6

Monkeypatching Widget是您最好的选择:

from django.forms.widgets import Widget
from django.contrib.admin.widgets import AdminFileWidget
from django.forms import HiddenInput, FileInput

old_build_attrs = Widget.build_attrs

def build_attrs(self, extra_attrs=None, **kwargs):
    attrs = old_build_attrs(self, extra_attrs, **kwargs)

    # if required, and it's not a file widget since those can have files
    # attached without seeming filled-in to the browser, and skip hidden "mock"
    # fileds created for StackedInline and TabbedInline admin stuff
    if (self.is_required
            and type(self) not in (AdminFileWidget, HiddenInput, FileInput)
            and "__prefix__" not in attrs.get("name", "")):
        attrs['required'] = 'required'

    return attrs

Widget.build_attrs = build_attrs
Run Code Online (Sandbox Code Playgroud)

  • 可能我建议您将if语句更改为:`if self.is_required并且键入(self)不在(AdminFileWidget,HiddenInput,FileInput)和"__prefix__"不在attrs ["name"]中:`这将阻止浏览器添加`required ="true"`当一个对象已经附加了一个文件时,以及跳过为StackedInline和TabbedInline管理员创建的隐藏的"模拟"字段. (4认同)

kar*_*yon 6

从Django 1.10开始,这是内置的.

发行说明:

现在,必填表单字段具有必需的HTML属性.将新的Form.use_required_attribute属性设置为False以禁用它.


Joh*_*ann 5

还有使用过滤器的仅模板解决方案.我建议django-widget-tweaks:

{% load widget_tweaks %}

{{ form.email|attr:'required:true' }}
Run Code Online (Sandbox Code Playgroud)

那很简单.