【发布时间】:2015-03-13 03:20:03
【问题描述】:
遇到错误后如何让提交的数据在表单集中重新显示? Django book 谈到了这一点,我能够使它在一个表单中工作,而不是在一个表单集中。
场景: 有 2 个必填字段 - 名字和姓氏。如果我只在名字字段中输入“John”而将姓氏字段留空并单击提交,我将收到一条错误消息,指出这两个字段都是必需的,并且表单清除了带有错误消息的提交数据。我想在名字字段中看到名字“John”以及错误消息。
非常感谢!
**forms.py**
from django import forms
from django.forms.formsets import BaseFormSet
class NameForm (forms.Form):
first_name = forms.CharField (max_length = 20, required = False)
last_name = forms.CharField (max_length = 20, required = False)
class BaseNameFormSet (BaseFormSet):
def clean (self):
if any (self.errors):
return
firstnames = []
lastnames = []
for form in self.forms:
firstname = form.cleaned_data.get ('first_name')
lastname = form.cleaned_data.get ('last_name')
if (firstname in firstnames) or (lastname in lastnames):
raise forms.ValidationError ('First or last name must be unique')
if (firstname == '') or (lastname == ''):
raise forms.ValidationError ('Both first and last name must be filled out')
firstnames.append (firstname)
lastnames.append (lastname)
return self.cleaned_data
**views.py**
from django.shortcuts import render
from django.forms.formsets import formset_factory
from nameform.forms import NameForm
from nameform.forms import BaseNameFormSet
from nameform.addName import webform
# Create your views here.
def addname (request):
# Set maximum to avoid default of 1000 forms.
NameFormSet = formset_factory (NameForm, formset = BaseNameFormSet, extra = 2, max_num = 5)
if request.method == 'POST':
# Django will become valid even if an empty form is submitted. Adding initial data causes unbound form and
# trigger formset.errors
# formset = NameFormSet (request.POST, initial = [{'first_name': 'John', 'last_name': 'Doe'}])
formset = NameFormSet (request.POST)
if formset.is_valid ():
location = request.POST ['site']
data = formset.cleaned_data
for form in data:
# Retrieving the value in an empty dictionary will result key error as it doesn't exist
# firstname = form ['first_name']
# lastname = form ['last_name']
firstname = form.get ('first_name')
lastname = form.get ('last_name')
if firstname and lastname:
webform (firstname, lastname, location)
context = {'data': data, 'location': location}
return render (request, 'nameform/success.html', context)
else:
formset = NameFormSet ()
return render (request, 'nameform/addname.html', {
'formset': formset,
'first_name': request.POST.get ('first_name', ''),
'last_name': request.POST.get ('last_name', '')
})
**addname.html**
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Add Name</title>
</head>
<body>
<h1>Add Name</h1>
<form action="" method="POST">{% csrf_token %}
<h3>Location:</h3>
<p><input type="radio" id="radio1" name="site" value="Location_A" checked>
<label for="radio1">Location A</label>
<input type="radio" id="radio2" name="site" value="Location_B">
<label for="radio2">Location B</label></p>
{{ formset.management_form }}
<label for="id_form-0-first_name">First Name:</label>
<input id="id_form-0-first_name" maxlength="20" name="form-0-first_name" type="text" value="{{ first_name }}" />
<label for="id_form-0-last_name">Last Name:</label>
<input id="id_form-0-last_name" maxlength="20" name="form-0-last_name" type="text" value="{{ last_name }}" />
<p><label for="id_form-1-first_name">First Name:</label>
<input id="id_form-1-first_name" maxlength="20" name="form-1-first_name" type="text" value="{{ first_name }}" />
<label for="id_form-1-last_name">Last Name:</label>
<input id="id_form-1-last_name" maxlength="20" name="form-1-last_name" type="text" value="{{ last_name }}" /></p>
<p><input type="submit" value="Add Name"></p>
</form>
{% if formset.errors %}
<p style="color: red;">Please correct the error below:</p>
{{ formset.non_form_errors }}
{% endif %}
</body>
</html>
在外壳中:
>>> partial_data = {
... 'form-TOTAL_FORMS': '2',
... 'form-INITIAL_FORMS': '0',
... 'form-MAX_NUM_FORMS': '3',
... 'form-0-first_name': 'John',
... 'form-0-last_name': 'Doe',
... 'form-1-first_name': 'James',
... 'form-1-last_name': ''
... }
>>>
>>> NameFormSet = formset_factory (NameForm, formset = BaseNameFormSet)
>>> formset = NameFormSet (partial_data)
>>>
>>> formset.is_valid ()
False
>>> formset.errors
[{}, {}]
>>> formset.non_form_errors ()
['Both first and last name must be filled out']
【问题讨论】: