我有一个具有以下自定义clean()方法的表单:
def clean(self):
cleaned_data = self.cleaned_data
event_date = cleaned_data.get("event_date")
location = cleaned_data.get("location")
if event_date and location:
cleaned_data['relevance'] = True
else:
cleaned_data['relevance'] = False
raise forms.ValidationError("You need to supply at least Event and Location information")
return cleaned_data
我想向用户显示ValidationError,以便他们可以修复错误 但是,创建此表单的formset具有extra = 0 set,如下所示:
CodingFormSet = formset_factory(CodingForm, extra=0)
if request.method=='POST':
[...]
elif "coding_form_save" in request.POST:
formset = CodingFormSet(request.POST, prefix="coding_form")
process_form(formset, request, current_page, paginator)
update_location_set(formset, coded_events, location_queryset)
redirect_to = "?page=%s" % current_page
return HttpResponseRedirect(redirect_to)
def process_form(formset, request, current_page, paginator):
if formset.is_valid():
for form in formset.forms:
form = form.cleaned_data
if form["relevance"] == False:
pass
elif form["relevance"] == True:
event_form = EventRecordForm()
event = event_form.save(commit=False)
event.article = paginator.page(current_page).object_list[0]
event.coder = request.user
event.last_updated = datetime.datetime.today()
event.event_date = form["event_date"]
event.location = form["location"]
event.actors = form["actors"]
event.num_participants = form["num_participants"]
event.issue = form["issue"]
event.side = form["side"]
event.scope = form["scope"]
event.part_violence = form["part_violence"]
event.sec_engagement = form["sec_engagement"]
event.save()
##### Add info on who worked on the article when
history_form = ArticleHistoryForm()
article_history = history_form.save(commit=False)
article_history.article = paginator.page(current_page).object_list[0]
article_history.coder = request.user
article_history.last_updated = datetime.datetime.now()
article_history.save()
有没有办法保持额外= 0并仍然显示用户验证错误?
的更新:
感谢@Alasdair,我现在可以通过仅在表单有效时重定向来显示验证错误。代码现在看起来像这样:
def assignment(request, pk):
"""View for each assignment"""
if request.user.is_authenticated():
#### Get correct articles
assignment = get_object_or_404(Assignment, pk=pk)
country = assignment.country.cowcode
start_date = assignment.start_date
end_date = assignment.end_date
articles = Article.objects.filter(cowcode=country).filter(pubdate__range=(start_date,end_date))
#### Pagination ####
paginator = Paginator(articles, 1)
page = request.GET.get('page')
try:
articles = paginator.page(page)
except PageNotAnInteger:
articles = paginator.page(1)
except EmptyPage:
articles = paginator(page(paginator.num_pages))
# Check if on first page and enable redirect
if page is None:
current_page = 1
else:
current_page = page
redirect_to = "?page=%s" % current_page
##### Show already created events on the page
current_article = paginator.page(current_page).object_list[0]
EventFormSet = modelformset_factory(EventRecord, can_delete=True, exclude=('coder','article','url','last_updated'), extra=0)
event_queryset = EventRecord.objects.filter(article__id=current_article.id).filter(coder=request.user.id)
coded_events = EventFormSet(queryset=event_queryset, prefix="event_form")
last_updated = ArticleHistory.objects.filter(coder=request.user.id).filter(article__id=current_article.id).order_by('-pk')[0]
##### Create Forms
CodingFormSet = formset_factory(CodingForm, extra=0)
###### Get correct locations
location_queryset = Geonames.objects.filter(cowcode=country).order_by('name')
if request.method=='POST':
##### Check if coder wants to go to next page or stay
if "coding_form_next" in request.POST:
formset = CodingFormSet(request.POST, prefix="coding_form")
process_form(formset, request, current_page, paginator, next_article, coded_events, location_queryset)
update_location_set(formset, coded_events, location_queryset)
#current_page = int(current_page) + 1
#redirect_to = "?page=%s" % current_page
#return HttpResponseRedirect(redirect_to)
elif "coding_form_save" in request.POST:
formset = CodingFormSet(request.POST, prefix="coding_form")
process_form(CodingFormSet, formset, request, current_page, paginator, next_article, coded_events, location_queryset)
update_location_set(formset, coded_events, location_queryset)
#redirect_to = "?page=%s" % current_page
#return HttpResponseRedirect(redirect_to)
elif 'add_event' in request.POST:
cp = request.POST.copy()
cp['coding_form-TOTAL_FORMS'] = int(cp['coding_form-TOTAL_FORMS'])+ 1
formset = CodingFormSet(cp,prefix='coding_form')
update_location_set(formset, coded_events, location_queryset)
elif 'save_changes' in request.POST:
formset = CodingFormSet(prefix="coding_form")
changed_events = EventFormSet(request.POST, prefix="event_form")
instances = changed_events.save()
update_location_set(formset, coded_events, location_queryset)
history_form = ArticleHistoryForm()
article_history = history_form.save(commit=False)
article_history.article = paginator.page(current_page).object_list[0]
article_history.coder = request.user
article_history.last_updated = datetime.datetime.now()
article_history.save()
EventFormSet = modelformset_factory(EventRecord, can_delete=True, exclude=('coder','article','url','last_updated'), extra=0)
event_queryset = EventRecord.objects.filter(article__id=current_article.id).filter(coder=request.user.id)
coded_events = EventFormSet(queryset=event_queryset, prefix="event_form")
else:
formset = CodingFormSet(request.POST or None,prefix="coding_form")
update_location_set(formset, coded_events, location_queryset)
else:
print ERROR
return render(request, 'coding/assignment.html',
{'articles':articles,'assignment':assignment,'formset':formset,'coded_events':coded_events,'last_updated':last_updated})
def process_form(CodingFormSet, formset, request, current_page, paginator, next_article, coded_events, location_queryset):
if formset.is_valid():
for form in formset.forms:
form = form.cleaned_data
if form["relevance"] == False:
pass
elif form["relevance"] == True:
event_form = EventRecordForm()
event = event_form.save(commit=False)
event.article = paginator.page(current_page).object_list[0]
event.coder = request.user
event.last_updated = datetime.datetime.today()
event.event_date = form["event_date"]
event.location = form["location"]
event.actors = form["actors"]
event.num_participants = form["num_participants"]
event.issue = form["issue"]
event.side = form["side"]
event.scope = form["scope"]
event.part_violence = form["part_violence"]
event.sec_engagement = form["sec_engagement"]
event.save()
##### Add info on who worked on the article when
history_form = ArticleHistoryForm()
article_history = history_form.save(commit=False)
article_history.article = paginator.page(current_page).object_list[0]
article_history.coder = request.user
article_history.last_updated = datetime.datetime.now()
article_history.save()
redirect_to = "?page=%s" % current_page
return HttpResponseRedirect(redirect_to)
然而,现在有什么不同,最好在三张图片中显示:
在旧代码中,在点击save
之后,编码器会看到以下内容:
现在,在点击save
之后,编码员看到了这一点:
看起来他根本没有点击保存。
只有在再次点击save
或重新加载页面后,他或她才会看到:
我想回到第一张图片,其中编码人员看到编码事件,而没有新的表格,其中包含相同的信息。请注意,他的发生是因为我改变了两行代码而没有做任何其他事情 非常感谢任何帮助!
答案 0 :(得分:1)
我不认为让extra=0
与是否显示错误有关。
以下模式在处理formset时非常常见:
def my_view(request):
if request.method == "POST"
formset = MyFormSet(request.POST, prefix="coding_form")
if formset.is_valid():
do_something_with_formset()
return HttpResponseRedirect("/success_url/")
else:
formset = MyFormSet(request.POST, prefix="coding_form")
return render(request, "my_template.html", {'formset': formset}
当请求方法为GET时,将呈现空白formset。当formset无效时,将呈现formset,并显示错误。我们只有在formset有效时才重定向。
在您的情况下,无论表单集是否有效,您始终在请求方法为POST时重定向。因此,当formset无效时,您永远不会看到错误。