gpt4 book ai didi

python - Django Formsets - form.is_valid() 为 False 阻止表单集验证

转载 作者:行者123 更新时间:2023-12-01 00:00:24 25 4
gpt4 key购买 nike

我正在利用表单集来使用户能够订阅多个提要。我要求 a) 用户通过选择 bool 字段来选择订阅,并且还需要标记订阅,b) 用户必须订阅指定数量的订阅。

目前,下面的代码能够 a) 确保用户标记订阅,但是我的一些表单 is_valid() 为 False,从而阻止了我对完整表单集的验证。 [编辑]此外,无法显示相关的表单集错误消息。

下面是代码:

from django import forms
from django.forms.formsets import BaseFormSet
from tagging.forms import TagField
from rss.feeder.models import Feed


class FeedForm(forms.Form):
subscribe = forms.BooleanField(required=False, initial=False)
tags = TagField(required=False, initial='')

def __init__(self, *args, **kwargs):
feed = kwargs.pop("feed")
super(FeedForm, self).__init__(*args, **kwargs)
self.title = feed.title
self.description = feed.description

def clean(self):
"""apply our custom validation rules"""
data = self.cleaned_data
feed = data.get("subscribe")
tags = data.get("tags")
tag_len = len(tags.split())
self._errors = {}
if feed == True and tag_len < 1:
raise forms.ValidationError("No tags specified for feed")
return data



class FeedFormSet(BaseFormSet):

def __init__(self, *args, **kwargs):
self.feeds = list(kwargs.pop("feeds"))
self.req_subs = 3 # TODO: convert to kwargs arguement
self.extra = len(self.feeds)
super(FeedFormSet, self).__init__(*args, **kwargs)

# WARNING! Using undocumented. see for details...
def _construct_form(self, i, **kwargs):
kwargs["feed"] = self.feeds[i]
return super(FeedFormSet, self)._construct_form(i, **kwargs)


def clean(self):
"""Checks that only a required number of Feed subscriptions are present"""
if any(self.errors):
# Do nothing, don't bother doing anything unless all the FeedForms are valid
return
total_subs = 0
for i in range(0, self.extra):
form = self.forms[i]
feed = form.cleaned_data
subs = feed.get("subscribe")
if subs == True:
total_subs += 1
if total_subs != self.req_subs:
raise forms.ValidationError("More subscriptions...") # TODO more informative
return form.cleaned_data

根据要求,查看代码:

from django.forms import formsets
from django.http import Http404
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

from rss.feeder.forms import FeedForm
from rss.feeder.forms import FeedFormSet
from rss.feeder.models import Feed

FeedSet = formsets.formset_factory(FeedForm, FeedFormSet)

def feeds(request):
if request.method == "POST":
formset = create_feed_formset(request.POST)
if formset.is_valid():
# submit the results
return HttpResponseRedirect('/feeder/thanks/')
else:
formset = create_feed_formset()
return render_to_response('feeder/register_step_two.html', {'formset': formset})


def create_feed_formset(data=None):
"""Create and populate a feed formset"""
feeds = Feed.objects.order_by('id')
if not feeds:
# No feeds found, we should have created them
raise Http404('Invalid Step')
return FeedSet(data, feeds=feeds) # return the instance of the formset

如有任何帮助,我们将不胜感激。

诗。为了充分披露,此代码基于 http://google.com/search?q=cache:rVtlfQ3QAjwJ:https://www.pointy-stick.com/blog/2009/01/23/advanced-formset-usage-django/+django+formset

[已解决] 请参阅下面的解决方案。

最佳答案

已解决。下面是解决方案的快速浏览。

报告错误需要处理和格式化特殊的错误消息。在表单集的源代码中,我发现适用于整个表单的错误被称为“non_form_errors”,并基于此生成了一个自定义错误。 [注意:我找不到任何关于此的权威文档,所以有人可能知道更好的方法]。代码如下:

def append_non_form_error(self, message):
errors = super(FeedFormSet, self).non_form_errors()
errors.append(message)
raise forms.ValidationError(errors)

表单集清理方法还需要一些调整。基本上,它检查表单是否已绑定(bind)(空表单未绑定(bind),因此问题中 is_valid 为 false),如果是,则访问检查订阅值。

def clean(self):
"""Checks that only a required number of Feed subscriptions are present"""
count = 0
for form in self.forms:
if form.is_bound:
if form['subscribe'].data:
count += 1
if count > 0 and count != self.required:
self.append_non_form_error("not enough subs")

有些人可能想知道为什么我选择使用 form['field_name'].data 格式访问该值。这使我们能够检索原始值并始终获得订阅计数,从而使我能够返回整个表单集的所有相关消息,即各个表单的特定问题和更高级别的问题(例如订阅数量),这意味着用户获胜不必一遍又一遍地重新提交表单来解决错误列表。

最后,我遗漏了模板的一个重要方面,即 {{ formset.non_form_errors }} 标签。以下是更新后的模板:

{% extends "base.html" %}
{% load i18n %}

{% block content %}
<form action="." method="post">
{{ formset.management_form }}
{{ formset.non_form_errors }}
<ol>
{% for form in formset.forms %}
<li><p>{{ form.title }}</p>
<p>{{ form.description }}</p>
{{ form.as_p }}
</li>
{% endfor %}
</ol>
<input type="submit">
</form>

{% endblock %}

关于python - Django Formsets - form.is_valid() 为 False 阻止表单集验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1682069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com