novalidate表单属性导致数据被省略

时间:2018-11-15 12:47:37

标签: django html5

HTML5允许某些表单元素的“浏览器端”验证;例如对于<input type="number">,如果您输入的不是数字,则会弹出一个小气泡。
 通过在表单标签上添加novalidate属性或在“提交”按钮上添加formnovalidate属性,可以抑制发送表单之前的验证,从而使服务器负责所有验证。
默认情况下,django使用novalidate,因为它的形式错误更容易被看到。

但是这里有个问题:使用novalidate时,可以验证客户端并且具有无效数据的任何 表单元素的数据,都将被忽略在到达服务器的请求中。服务器不再能够验证这些错误元素的数据,结果,输入错误数据的用户将永远不会意识到自己的错误。

forms.py

class WorstFormEver(Form):
    a = IntegerField(required = False) # use the default NumberInput widget, allowing HTML5 validation
    b = IntegerField(required = False, widget = TextInput) # TextInput does not include HTML5 validation

采用此表格,并在两个字段中都填写字母。

views.py

class WorstViewEver(FormView):
    form_class = WorstFormEver
    template_name = 'admin/worst.html'
    success_url = reverse_lazy('worst')
    novalidate = True

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['novalidate'] = self.novalidate
        return context

    def post(self, request, *args, **kwargs):
        print(self.request.POST.get('a','PANIC!')) # prints [''] if self.novalidate is True
        return super().post(request, *args, **kwargs)

人们希望该视图返回带有两个字段均具有错误的表单的响应,但是当b空a字段的错误>! a的无效数据甚至从未发送到服务器。

带有novalidate的表单-request.POST包含'a': [''], 'b': ['bar']Form with novalidate

没有novalidate的表单-出现错误时无法发布该表单: Form without novalidate

模板

{% extends 'admin/base_site.html' %}

{% block content %}
<form method="post" {% if novalidate %}novalidate{% endif %}>
    {% csrf_token %}
    {{ form }}
    <input type="submit">
</form>
{% endblock content %}

删除novalidate甚至都不会让您发送表单(如预期的那样)。
我也可以将所有可能支持HTML5验证的小部件替换为无聊的旧TextInput小部件,但这感觉更像是对待症状而不是原因。

我宁愿不使用HTML5验证,因为某些形式可能非常大,而django的错误表示则更加清晰(而且内容丰富)。

我的问题是如何使用novalidate(因为我想同时使用特定于字段的窗口小部件和仅django的验证)而不会丢失数据。问题是,尽管明确设置了novalidate某事仍在进行某种验证并删除数据。

使用: django v1.11,以上示例在Firefox上进行了测试

0 个答案:

没有答案