如何根据Django中的formset_factory设置所需的每个字段(如何验证表单集中的空白表单)

问题描述 投票:1回答:1

我的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函数获取表单集中表单的初始数据。因此,如果我有三个表单,则在任何一个表单中,如果其中一个字段为空白(无用户输入),则当我单击“更新”按钮时,每个空白字段均应使用“此字段必填”突出显示。当我仅呈现常规表单时可以执行此操作,但是当我使用表单集时,它不起作用。

是否有方法可以在发送请求之前验证表单集中的表单?

django-forms django-templates formset
1个回答
0
投票

我遇到了同样的问题,并在文档中找到了此问题

https://docs.djangoproject.com/en/3.0/ref/forms/fields/#core-field-arguments

必填表格字段的小部件具有必填的HTML属性。将Form.use_required_attribute属性设置为False以禁用它。表单集的表单中未包含必填属性,因为添加和删除表单集时浏览器验证可能不正确。

如果在您的方案中可行,可以通过为表单集中的每一行(“表单”)设置Form.use_required_attribute = True来解决此问题。

但是,如果您有一个空行(用于添加额外的记录),那么您将无法保存表单,直到填写了空行。因此,如果您要说更新一个现有行而不添加额外的行,那么您可以有问题,你不能做。问题确实来自这样一个事实,即表单集实际上只是html形式的一种表单。该问题的一种可能的解决方法(我尚未尝试过)可能是仅根据需要使用javascript将行添加到表单集中,如本示例所示:

https://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html

上面的示例还向您展示了如果愿意的话,如何在clean方法中验证表单集字段。在发送请求之前,可能还有一个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

该解决方案似乎可以正常工作,当我单击“添加”按钮时,会出现一个空行,并且空的“名称”字段在空字段周围有预期的红色框,当我尝试单击“保存”时,会收到消息“请填写这个领域。'

© www.soinside.com 2019 - 2024. All rights reserved.