Django内联表单集自定义验证仅逐个验证单个表单集。

3
我正在使用Django,并有一个带有两个额外的内联表单集的表单。我想验证每个表单集是否至少包含一个填充的表单。我已经编写了代码,使其可以工作,但是它只适用于每个表单集一次。如果我提交没有填充表单集表单的表单,则只有第一个表单集显示验证错误。如果我然后填充第一个表单集表单,并将第二个表单留空,则第二个表单会出现错误。
如果两个表单都无效,我希望两个表单上都显示错误。
这些表单只是标准的ModelForm实例。以下是我的视图:
class RequiredBaseInlineFormSet(BaseInlineFormSet):
    def clean(self):
        self.validate_unique()
        if any(self.errors):
            return
        if not self.forms[0].has_changed():
            raise forms.ValidationError("At least one %s is required" % self.model._meta.verbose_name)

def create(request):
    profile_form = ProfileForm(request.POST or None)
    EmailFormSet = inlineformset_factory(Profile, Email, formset=RequiredBaseInlineFormSet, max_num=5, extra=5, can_delete=False)
    email_formset = EmailFormSet(request.POST or None)
    PhoneFormSet = inlineformset_factory(Profile, Phone, formset=RequiredBaseInlineFormSet, max_num=5, extra=5, can_delete=False)
    phone_formset = PhoneFormSet(request.POST or None)
    if profile_form.is_valid() and email_formset.is_valid() and phone_formset.is_valid():
        profile = profile_form.save()
        emails = email_formset.save(commit=False)
        for email in emails:
            email.profile = profile
            email.save()
        phones = phone_formset.save(commit=False)
        for phone in phones:
            phone.profile = profile
            phone.save()
        messages.add_message(request, messages.INFO, 'Profile successfully saved')
    return render_to_response(
        'add.html', {
            'profile_form': profile_form,
            'email_formset': email_formset,
            'phone_formset': phone_formset
        }, context_instance = RequestContext(request)
    )

这是我的模板表单,如果有用的话:

<form action="" method="post" accept-charset="utf-8">
    {{ email_formset.management_form }}
    {{ phone_formset.management_form }}
    {{ profile_form|as_uni_form }}
    <div class="formset-group" id="email_formset">
        {{ email_formset.non_form_errors }}
        {% for email_form in email_formset.forms %}
            <div class='form'>
                {{ email_form|as_uni_form }}
            </div>
        {% endfor %}
    </div>
    <div class="formset-group" id="phone_formset">
        {{ phone_formset.non_form_errors }}
        {% for phone_form in phone_formset.forms %}
            <div class='form'>
                {{ phone_form|as_uni_form }}
            </div>
        {% endfor %}
    </div>
    <input type="submit" value="Save Profile" id="submit">
</form>
2个回答

2

对于您希望进行验证的每个表单,请调用is_valid()函数。在您的示例中,您使用if a.is_valid and b.is_valid和c.is_valid...如果a为false,则b和c将永远不会被调用。尝试一些不同的东西,比如:

alpha=a.is_valid()
beta=b.is_valid()
gamma=c.is_valid()

if alpha and beta and gamma: 
  do stuff

我认为你是对的。我之前离开了这个问题,但现在我回来了,并且已经成功地将所有表单集合放入一个列表中,并使用all()进行验证,例如:if profile_form.is_valid() and all([fs.is_valid() for fs in formsets]): 感谢你的建议。 - Tim Fletcher

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接