如何在 Django 中根据需要为 formset_factory 设置每个字段(如何验证表单集中的空白表单)
Posted
技术标签:
【中文标题】如何在 Django 中根据需要为 formset_factory 设置每个字段(如何验证表单集中的空白表单)【英文标题】:How to set each field as required for formset_factory in Django (how to validate blank forms in formsets) 【发布时间】:2020-06-07 03:55:52 【问题描述】:我的 forms.py 中有表单:
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
age = forms.CharField(label='Age', max_length=100)
sex = forms.CharField(label='Sex', max_length=100)
我创建了 formset_factory
NameFormSet = formset_factory(NameForm, extra=0)
在获取 context_data 的 views.py 中,我有:
...
def get_context_data(self, **kwargs):
context = super(APView, self).get_context_data(**kwargs)
if self.request.POST:
context['formset'] = NameFormSet()
else:
recommended = returnWebAttackResults(self.kwargs['webAttack'])
if recommended is None:
context['recommendedAP'] = False
else:
context['formset'] = NameFormSet(initial=recommended[0])
return context
....
在我的模板文件中,我有:
<form class="row" method="POST" enctype="multipart/form-data">
% csrf_token %
formset.management_form
formset.non_form_errors
% for forma in formset.forms %
forma
% endfor %
<input class="btn bg-success" type="submit" value="Update" />
</form>
我的问题是当我单击“更新”按钮时,我没有得到“此字段是必需的”。我尝试将 use_required_attribute 设置为 True,但没有成功。
场景:
returnWebAttackResults 函数获取表单集中表单的初始数据。因此,如果我有三个表单,如果任何表单中的一个字段为空白(无用户输入),那么当我单击更新按钮时,每个空白字段都应突出显示“此字段是必需的” .我只渲染常规表单时可以这样做,但是当我使用表单集时,它不起作用。
有没有办法在发送请求之前验证表单集中的表单?
【问题讨论】:
【参考方案1】:我遇到了同样的问题,并在文档中找到了这个
https://docs.djangoproject.com/en/3.0/ref/forms/fields/#core-field-arguments
必需表单字段的小部件具有必需的 html 属性。将 Form.use_required_attribute 属性设置为 False 以禁用它。表单集的表单中不包含 required 属性,因为添加和删除表单集时浏览器验证可能不正确。
如果您有一个空行(用于添加额外记录),则在填写空行之前您无法保存表单。因此,如果您想说更新一个现有行而不添加额外行,那么您有问题,你做不到。问题实际上来自这样一个事实,即表单集实际上在 html 术语中只是一个表单。该问题的解决方法可能是仅在需要时使用 javascript 将行添加到表单集,如下例所示:
https://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html
可能还有一个javascript解决方案可以在您发送请求之前验证表单字段,我认为这可能是这样的解决方案,但我还没有尝试过:
https://jqueryvalidation.org/required-method/
不应该为必填字段验证完全空的行,而是完全忽略它是有道理的。
更新:我从上面链接中的示例中得到了一个简单的解决方案。我的模板看起来像这样(请注意,由于 if 语句,最初没有显示空行):
% extends "base_generic.html" %
% load static %
% block content %
<h1>Experiment Detail</h1>
<form name="test_form" method="post">
% csrf_token %
formset.management_form
% for form in formset %
% if form.name.value %
<div class="link-formset">
form.name
</div>
% endif %
% endfor %
<input type="submit" value="Save" class="button"/>
</form>
<!-- Include formset plugin - including jQuery dependency -->
<!-- <script src="% static 'path_to/jquery-3.4.1.js' %"></script> -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="% static 'js/jquery_formset.js' %"></script>
<script>
$('.link-formset').formset(
addText: 'Add',
deleteText: 'Delete'
);
</script>
% endblock %
在我看来,我有这个 for 循环来设置 use_required_attribute:
for form in formSet:
form.use_required_attribute = True
解决方案似乎工作正常,当我单击“添加”按钮时,会出现一个空行,并且空的“名称”字段在空字段周围有预期的红色框,当我尝试单击“保存”时,我收到消息“请填写走出这个领域。'
【讨论】:
以上是关于如何在 Django 中根据需要为 formset_factory 设置每个字段(如何验证表单集中的空白表单)的主要内容,如果未能解决你的问题,请参考以下文章
Django - 基数为 10 的 int() 的 Formset 无效文字:''
与 django-dynamic-formset 一起使用的 Django Formset 不显示删除链接
Django 和 jQuery.formset,如何操作删除按钮位置