mirror of https://github.com/django/django.git
Changed the fix from [5231] so that the backwards-incompatibility is made more
obvious and everything still has nice names. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5237 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
41fbd35613
commit
b996e214c0
|
@ -24,7 +24,7 @@ Usage
|
||||||
|
|
||||||
Subclass FormPreview and define a done() method:
|
Subclass FormPreview and define a done() method:
|
||||||
|
|
||||||
def done(self, request, clean_data):
|
def done(self, request, cleaned_data):
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
This method takes an HttpRequest object and a dictionary of the form data after
|
This method takes an HttpRequest object and a dictionary of the form data after
|
||||||
|
@ -113,7 +113,7 @@ class FormPreview(object):
|
||||||
if f.is_valid():
|
if f.is_valid():
|
||||||
if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')):
|
if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')):
|
||||||
return self.failed_hash(request) # Security hash failed.
|
return self.failed_hash(request) # Security hash failed.
|
||||||
return self.done(request, f.clean_data)
|
return self.done(request, f.cleaned_data)
|
||||||
else:
|
else:
|
||||||
return render_to_response(self.form_template,
|
return render_to_response(self.form_template,
|
||||||
{'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state},
|
{'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state},
|
||||||
|
@ -160,6 +160,9 @@ class FormPreview(object):
|
||||||
|
|
||||||
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
||||||
|
|
||||||
def done(self, request, clean_data):
|
def done(self, request, cleaned_data):
|
||||||
"Does something with the clean_data and returns an HttpResponseRedirect."
|
"""
|
||||||
|
Does something with the cleaned_data and returns an
|
||||||
|
HttpResponseRedirect.
|
||||||
|
"""
|
||||||
raise NotImplementedError('You must define a done() method on your %s subclass.' % self.__class__.__name__)
|
raise NotImplementedError('You must define a done() method on your %s subclass.' % self.__class__.__name__)
|
||||||
|
|
|
@ -169,13 +169,13 @@ class BaseForm(StrAndUnicode):
|
||||||
|
|
||||||
def full_clean(self):
|
def full_clean(self):
|
||||||
"""
|
"""
|
||||||
Cleans all of self.data and populates self.__errors and self.clean_data.
|
Cleans all of self.data and populates self.__errors and self.cleaned_data.
|
||||||
"""
|
"""
|
||||||
errors = ErrorDict()
|
errors = ErrorDict()
|
||||||
if not self.is_bound: # Stop further processing.
|
if not self.is_bound: # Stop further processing.
|
||||||
self.__errors = errors
|
self.__errors = errors
|
||||||
return
|
return
|
||||||
self.clean_data = {}
|
self.cleaned_data = {}
|
||||||
for name, field in self.fields.items():
|
for name, field in self.fields.items():
|
||||||
# value_from_datadict() gets the data from the dictionary.
|
# value_from_datadict() gets the data from the dictionary.
|
||||||
# Each widget type knows how to retrieve its own data, because some
|
# Each widget type knows how to retrieve its own data, because some
|
||||||
|
@ -183,18 +183,18 @@ class BaseForm(StrAndUnicode):
|
||||||
value = field.widget.value_from_datadict(self.data, self.add_prefix(name))
|
value = field.widget.value_from_datadict(self.data, self.add_prefix(name))
|
||||||
try:
|
try:
|
||||||
value = field.clean(value)
|
value = field.clean(value)
|
||||||
self.clean_data[name] = value
|
self.cleaned_data[name] = value
|
||||||
if hasattr(self, 'do_clean_%s' % name):
|
if hasattr(self, 'clean_%s' % name):
|
||||||
value = getattr(self, 'do_clean_%s' % name)()
|
value = getattr(self, 'clean_%s' % name)()
|
||||||
self.clean_data[name] = value
|
self.cleaned_data[name] = value
|
||||||
except ValidationError, e:
|
except ValidationError, e:
|
||||||
errors[name] = e.messages
|
errors[name] = e.messages
|
||||||
try:
|
try:
|
||||||
self.clean_data = self.clean()
|
self.cleaned_data = self.clean()
|
||||||
except ValidationError, e:
|
except ValidationError, e:
|
||||||
errors[NON_FIELD_ERRORS] = e.messages
|
errors[NON_FIELD_ERRORS] = e.messages
|
||||||
if errors:
|
if errors:
|
||||||
delattr(self, 'clean_data')
|
delattr(self, 'cleaned_data')
|
||||||
self.__errors = errors
|
self.__errors = errors
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
@ -204,7 +204,7 @@ class BaseForm(StrAndUnicode):
|
||||||
not be associated with a particular field; it will have a special-case
|
not be associated with a particular field; it will have a special-case
|
||||||
association with the field named '__all__'.
|
association with the field named '__all__'.
|
||||||
"""
|
"""
|
||||||
return self.clean_data
|
return self.cleaned_data
|
||||||
|
|
||||||
class Form(BaseForm):
|
class Form(BaseForm):
|
||||||
"A collection of Fields, plus their associated data."
|
"A collection of Fields, plus their associated data."
|
||||||
|
|
|
@ -14,7 +14,7 @@ __all__ = ('save_instance', 'form_for_model', 'form_for_instance', 'form_for_fie
|
||||||
|
|
||||||
def save_instance(form, instance, fields=None, fail_message='saved', commit=True):
|
def save_instance(form, instance, fields=None, fail_message='saved', commit=True):
|
||||||
"""
|
"""
|
||||||
Saves bound Form ``form``'s clean_data into model instance ``instance``.
|
Saves bound Form ``form``'s cleaned_data into model instance ``instance``.
|
||||||
|
|
||||||
Assumes ``form`` has a field for every non-AutoField database field in
|
Assumes ``form`` has a field for every non-AutoField database field in
|
||||||
``instance``. If commit=True, then the changes to ``instance`` will be
|
``instance``. If commit=True, then the changes to ``instance`` will be
|
||||||
|
@ -24,20 +24,20 @@ def save_instance(form, instance, fields=None, fail_message='saved', commit=True
|
||||||
opts = instance.__class__._meta
|
opts = instance.__class__._meta
|
||||||
if form.errors:
|
if form.errors:
|
||||||
raise ValueError("The %s could not be %s because the data didn't validate." % (opts.object_name, fail_message))
|
raise ValueError("The %s could not be %s because the data didn't validate." % (opts.object_name, fail_message))
|
||||||
clean_data = form.clean_data
|
cleaned_data = form.cleaned_data
|
||||||
for f in opts.fields:
|
for f in opts.fields:
|
||||||
if not f.editable or isinstance(f, models.AutoField) or not f.name in clean_data:
|
if not f.editable or isinstance(f, models.AutoField) or not f.name in cleaned_data:
|
||||||
continue
|
continue
|
||||||
if fields and f.name not in fields:
|
if fields and f.name not in fields:
|
||||||
continue
|
continue
|
||||||
setattr(instance, f.name, clean_data[f.name])
|
setattr(instance, f.name, cleaned_data[f.name])
|
||||||
if commit:
|
if commit:
|
||||||
instance.save()
|
instance.save()
|
||||||
for f in opts.many_to_many:
|
for f in opts.many_to_many:
|
||||||
if fields and f.name not in fields:
|
if fields and f.name not in fields:
|
||||||
continue
|
continue
|
||||||
if f.name in clean_data:
|
if f.name in cleaned_data:
|
||||||
setattr(instance, f.attname, clean_data[f.name])
|
setattr(instance, f.attname, cleaned_data[f.name])
|
||||||
# GOTCHA: If many-to-many data is given and commit=False, the many-to-many
|
# GOTCHA: If many-to-many data is given and commit=False, the many-to-many
|
||||||
# data will be lost. This happens because a many-to-many options cannot be
|
# data will be lost. This happens because a many-to-many options cannot be
|
||||||
# set on an object until after it's saved. Maybe we should raise an
|
# set on an object until after it's saved. Maybe we should raise an
|
||||||
|
|
|
@ -230,7 +230,7 @@ object. Regardless of whether you pass it a string in the format
|
||||||
it's valid.
|
it's valid.
|
||||||
|
|
||||||
Once you've created a ``Form`` instance with a set of data and validated it,
|
Once you've created a ``Form`` instance with a set of data and validated it,
|
||||||
you can access the clean data via the ``clean_data`` attribute of the ``Form``
|
you can access the clean data via the ``cleaned_data`` attribute of the ``Form``
|
||||||
object::
|
object::
|
||||||
|
|
||||||
>>> data = {'subject': 'hello',
|
>>> data = {'subject': 'hello',
|
||||||
|
@ -240,7 +240,7 @@ object::
|
||||||
>>> f = ContactForm(data)
|
>>> f = ContactForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
|
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
|
||||||
|
|
||||||
Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
|
Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
|
||||||
|
@ -248,7 +248,7 @@ always cleans the input into a Unicode string. We'll cover the encoding
|
||||||
implications later in this document.
|
implications later in this document.
|
||||||
|
|
||||||
If your data does *not* validate, your ``Form`` instance will not have a
|
If your data does *not* validate, your ``Form`` instance will not have a
|
||||||
``clean_data`` attribute::
|
``cleaned_data`` attribute::
|
||||||
|
|
||||||
>>> data = {'subject': '',
|
>>> data = {'subject': '',
|
||||||
... 'message': 'Hi there',
|
... 'message': 'Hi there',
|
||||||
|
@ -257,15 +257,15 @@ If your data does *not* validate, your ``Form`` instance will not have a
|
||||||
>>> f = ContactForm(data)
|
>>> f = ContactForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
False
|
False
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'ContactForm' object has no attribute 'clean_data'
|
AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
|
||||||
|
|
||||||
``clean_data`` will always *only* contain a key for fields defined in the
|
``cleaned_data`` will always *only* contain a key for fields defined in the
|
||||||
``Form``, even if you pass extra data when you define the ``Form``. In this
|
``Form``, even if you pass extra data when you define the ``Form``. In this
|
||||||
example, we pass a bunch of extra fields to the ``ContactForm`` constructor,
|
example, we pass a bunch of extra fields to the ``ContactForm`` constructor,
|
||||||
but ``clean_data`` contains only the form's fields::
|
but ``cleaned_data`` contains only the form's fields::
|
||||||
|
|
||||||
>>> data = {'subject': 'hello',
|
>>> data = {'subject': 'hello',
|
||||||
... 'message': 'Hi there',
|
... 'message': 'Hi there',
|
||||||
|
@ -277,13 +277,13 @@ but ``clean_data`` contains only the form's fields::
|
||||||
>>> f = ContactForm(data)
|
>>> f = ContactForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data # Doesn't contain extra_field_1, etc.
|
>>> f.cleaned_data # Doesn't contain extra_field_1, etc.
|
||||||
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
|
{'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
|
||||||
|
|
||||||
``clean_data`` will include a key and value for *all* fields defined in the
|
``cleaned_data`` will include a key and value for *all* fields defined in the
|
||||||
``Form``, even if the data didn't include a value for fields that are not
|
``Form``, even if the data didn't include a value for fields that are not
|
||||||
required. In this example, the data dictionary doesn't include a value for the
|
required. In this example, the data dictionary doesn't include a value for the
|
||||||
``nick_name`` field, but ``clean_data`` includes it, with an empty value::
|
``nick_name`` field, but ``cleaned_data`` includes it, with an empty value::
|
||||||
|
|
||||||
>>> class OptionalPersonForm(Form):
|
>>> class OptionalPersonForm(Form):
|
||||||
... first_name = CharField()
|
... first_name = CharField()
|
||||||
|
@ -293,10 +293,10 @@ required. In this example, the data dictionary doesn't include a value for the
|
||||||
>>> f = OptionalPersonForm(data)
|
>>> f = OptionalPersonForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
|
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
|
||||||
|
|
||||||
In this above example, the ``clean_data`` value for ``nick_name`` is set to an
|
In this above example, the ``cleaned_data`` value for ``nick_name`` is set to an
|
||||||
empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
|
empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
|
||||||
empty values as an empty string. Each field type knows what its "blank" value
|
empty values as an empty string. Each field type knows what its "blank" value
|
||||||
is -- e.g., for ``DateField``, it's ``None`` instead of the empty string.
|
is -- e.g., for ``DateField``, it's ``None`` instead of the empty string.
|
||||||
|
@ -308,10 +308,10 @@ It's meaningless to request "clean" data in a form with no data, but, for the
|
||||||
record, here's what happens with unbound forms::
|
record, here's what happens with unbound forms::
|
||||||
|
|
||||||
>>> f = ContactForm()
|
>>> f = ContactForm()
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'ContactForm' object has no attribute 'clean_data'
|
AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
|
||||||
|
|
||||||
Outputting forms as HTML
|
Outputting forms as HTML
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
@ -18,7 +18,7 @@ other Form, with one additional method: save(). The save()
|
||||||
method updates the model instance. It also takes a commit=True parameter.
|
method updates the model instance. It also takes a commit=True parameter.
|
||||||
|
|
||||||
The function django.newforms.save_instance() takes a bound form instance and a
|
The function django.newforms.save_instance() takes a bound form instance and a
|
||||||
model instance and saves the form's clean_data into the instance. It also takes
|
model instance and saves the form's cleaned_data into the instance. It also takes
|
||||||
a commit=True parameter.
|
a commit=True parameter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ __test__ = {'API_TESTS': """
|
||||||
>>> f = CategoryForm({'name': 'Entertainment', 'url': 'entertainment'})
|
>>> f = CategoryForm({'name': 'Entertainment', 'url': 'entertainment'})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'url': u'entertainment', 'name': u'Entertainment'}
|
{'url': u'entertainment', 'name': u'Entertainment'}
|
||||||
>>> obj = f.save()
|
>>> obj = f.save()
|
||||||
>>> obj
|
>>> obj
|
||||||
|
@ -105,7 +105,7 @@ True
|
||||||
>>> f = CategoryForm({'name': "It's a test", 'url': 'test'})
|
>>> f = CategoryForm({'name': "It's a test", 'url': 'test'})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'url': u'test', 'name': u"It's a test"}
|
{'url': u'test', 'name': u"It's a test"}
|
||||||
>>> obj = f.save()
|
>>> obj = f.save()
|
||||||
>>> obj
|
>>> obj
|
||||||
|
@ -119,7 +119,7 @@ save() on the resulting model instance.
|
||||||
>>> f = CategoryForm({'name': 'Third test', 'url': 'third'})
|
>>> f = CategoryForm({'name': 'Third test', 'url': 'third'})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'url': u'third', 'name': u'Third test'}
|
{'url': u'third', 'name': u'Third test'}
|
||||||
>>> obj = f.save(commit=False)
|
>>> obj = f.save(commit=False)
|
||||||
>>> obj
|
>>> obj
|
||||||
|
@ -134,10 +134,10 @@ If you call save() with invalid data, you'll get a ValueError.
|
||||||
>>> f = CategoryForm({'name': '', 'url': 'foo'})
|
>>> f = CategoryForm({'name': '', 'url': 'foo'})
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{'name': [u'This field is required.']}
|
{'name': [u'This field is required.']}
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'CategoryForm' object has no attribute 'clean_data'
|
AttributeError: 'CategoryForm' object has no attribute 'cleaned_data'
|
||||||
>>> f.save()
|
>>> f.save()
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
|
@ -524,6 +524,6 @@ ValidationError: [u'Select a valid choice. 10 is not one of the available choice
|
||||||
>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'})
|
>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'phone': u'312-555-1212', 'description': u'Assistance'}
|
{'phone': u'312-555-1212', 'description': u'Assistance'}
|
||||||
"""}
|
"""}
|
||||||
|
|
|
@ -46,6 +46,6 @@ doesn't come back.
|
||||||
>>> f = DataForm({'data': 'xyzzy'})
|
>>> f = DataForm({'data': 'xyzzy'})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'data': u'xyzzy'}
|
{'data': u'xyzzy'}
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1774,7 +1774,7 @@ True
|
||||||
u''
|
u''
|
||||||
>>> p.errors.as_text()
|
>>> p.errors.as_text()
|
||||||
u''
|
u''
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
||||||
>>> print p['first_name']
|
>>> print p['first_name']
|
||||||
<input type="text" name="first_name" value="John" id="id_first_name" />
|
<input type="text" name="first_name" value="John" id="id_first_name" />
|
||||||
|
@ -1810,10 +1810,10 @@ True
|
||||||
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
|
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
|
||||||
>>> p.is_valid()
|
>>> p.is_valid()
|
||||||
False
|
False
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'Person' object has no attribute 'clean_data'
|
AttributeError: 'Person' object has no attribute 'cleaned_data'
|
||||||
>>> print p
|
>>> print p
|
||||||
<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
|
<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
|
||||||
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
|
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
|
||||||
|
@ -1844,10 +1844,10 @@ False
|
||||||
{}
|
{}
|
||||||
>>> p.is_valid()
|
>>> p.is_valid()
|
||||||
False
|
False
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'Person' object has no attribute 'clean_data'
|
AttributeError: 'Person' object has no attribute 'cleaned_data'
|
||||||
>>> print p
|
>>> print p
|
||||||
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
|
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
|
||||||
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
|
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
|
||||||
|
@ -1886,10 +1886,10 @@ u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is re
|
||||||
* This field is required.
|
* This field is required.
|
||||||
* birthday
|
* birthday
|
||||||
* This field is required.
|
* This field is required.
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
AttributeError: 'Person' object has no attribute 'clean_data'
|
AttributeError: 'Person' object has no attribute 'cleaned_data'
|
||||||
>>> p['first_name'].errors
|
>>> p['first_name'].errors
|
||||||
[u'This field is required.']
|
[u'This field is required.']
|
||||||
>>> p['first_name'].errors.as_ul()
|
>>> p['first_name'].errors.as_ul()
|
||||||
|
@ -1905,21 +1905,21 @@ u'* This field is required.'
|
||||||
>>> print p['birthday']
|
>>> print p['birthday']
|
||||||
<input type="text" name="birthday" id="id_birthday" />
|
<input type="text" name="birthday" id="id_birthday" />
|
||||||
|
|
||||||
clean_data will always *only* contain a key for fields defined in the
|
cleaned_data will always *only* contain a key for fields defined in the
|
||||||
Form, even if you pass extra data when you define the Form. In this
|
Form, even if you pass extra data when you define the Form. In this
|
||||||
example, we pass a bunch of extra fields to the form constructor,
|
example, we pass a bunch of extra fields to the form constructor,
|
||||||
but clean_data contains only the form's fields.
|
but cleaned_data contains only the form's fields.
|
||||||
>>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'}
|
>>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'}
|
||||||
>>> p = Person(data)
|
>>> p = Person(data)
|
||||||
>>> p.is_valid()
|
>>> p.is_valid()
|
||||||
True
|
True
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
||||||
|
|
||||||
clean_data will include a key and value for *all* fields defined in the Form,
|
cleaned_data will include a key and value for *all* fields defined in the Form,
|
||||||
even if the Form's data didn't include a value for fields that are not
|
even if the Form's data didn't include a value for fields that are not
|
||||||
required. In this example, the data dictionary doesn't include a value for the
|
required. In this example, the data dictionary doesn't include a value for the
|
||||||
"nick_name" field, but clean_data includes it. For CharFields, it's set to the
|
"nick_name" field, but cleaned_data includes it. For CharFields, it's set to the
|
||||||
empty string.
|
empty string.
|
||||||
>>> class OptionalPersonForm(Form):
|
>>> class OptionalPersonForm(Form):
|
||||||
... first_name = CharField()
|
... first_name = CharField()
|
||||||
|
@ -1929,7 +1929,7 @@ empty string.
|
||||||
>>> f = OptionalPersonForm(data)
|
>>> f = OptionalPersonForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
|
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
|
||||||
|
|
||||||
For DateFields, it's set to None.
|
For DateFields, it's set to None.
|
||||||
|
@ -1941,7 +1941,7 @@ For DateFields, it's set to None.
|
||||||
>>> f = OptionalPersonForm(data)
|
>>> f = OptionalPersonForm(data)
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'birth_date': None, 'first_name': u'John', 'last_name': u'Lennon'}
|
{'birth_date': None, 'first_name': u'John', 'last_name': u'Lennon'}
|
||||||
|
|
||||||
"auto_id" tells the Form to add an "id" attribute to each form element.
|
"auto_id" tells the Form to add an "id" attribute to each form element.
|
||||||
|
@ -2292,19 +2292,19 @@ returns a list of input.
|
||||||
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
|
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'composers': [u'J'], 'name': u'Yesterday'}
|
{'composers': [u'J'], 'name': u'Yesterday'}
|
||||||
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
|
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'composers': [u'J', u'P'], 'name': u'Yesterday'}
|
{'composers': [u'J', u'P'], 'name': u'Yesterday'}
|
||||||
|
|
||||||
Validation errors are HTML-escaped when output as HTML.
|
Validation errors are HTML-escaped when output as HTML.
|
||||||
>>> class EscapingForm(Form):
|
>>> class EscapingForm(Form):
|
||||||
... special_name = CharField()
|
... special_name = CharField()
|
||||||
... def do_clean_special_name(self):
|
... def clean_special_name(self):
|
||||||
... raise ValidationError("Something's wrong with '%s'" % self.clean_data['special_name'])
|
... raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name'])
|
||||||
|
|
||||||
>>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
|
>>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
|
||||||
>>> print f
|
>>> print f
|
||||||
|
@ -2319,17 +2319,17 @@ There are a couple of ways to do multiple-field validation. If you want the
|
||||||
validation message to be associated with a particular field, implement the
|
validation message to be associated with a particular field, implement the
|
||||||
clean_XXX() method on the Form, where XXX is the field name. As in
|
clean_XXX() method on the Form, where XXX is the field name. As in
|
||||||
Field.clean(), the clean_XXX() method should return the cleaned value. In the
|
Field.clean(), the clean_XXX() method should return the cleaned value. In the
|
||||||
clean_XXX() method, you have access to self.clean_data, which is a dictionary
|
clean_XXX() method, you have access to self.cleaned_data, which is a dictionary
|
||||||
of all the data that has been cleaned *so far*, in order by the fields,
|
of all the data that has been cleaned *so far*, in order by the fields,
|
||||||
including the current field (e.g., the field XXX if you're in clean_XXX()).
|
including the current field (e.g., the field XXX if you're in clean_XXX()).
|
||||||
>>> class UserRegistration(Form):
|
>>> class UserRegistration(Form):
|
||||||
... username = CharField(max_length=10)
|
... username = CharField(max_length=10)
|
||||||
... password1 = CharField(widget=PasswordInput)
|
... password1 = CharField(widget=PasswordInput)
|
||||||
... password2 = CharField(widget=PasswordInput)
|
... password2 = CharField(widget=PasswordInput)
|
||||||
... def do_clean_password2(self):
|
... def clean_password2(self):
|
||||||
... if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
|
... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
|
||||||
... raise ValidationError(u'Please make sure your passwords match.')
|
... raise ValidationError(u'Please make sure your passwords match.')
|
||||||
... return self.clean_data['password2']
|
... return self.cleaned_data['password2']
|
||||||
>>> f = UserRegistration(auto_id=False)
|
>>> f = UserRegistration(auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
|
@ -2342,14 +2342,14 @@ including the current field (e.g., the field XXX if you're in clean_XXX()).
|
||||||
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
|
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
|
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
|
||||||
|
|
||||||
Another way of doing multiple-field validation is by implementing the
|
Another way of doing multiple-field validation is by implementing the
|
||||||
Form's clean() method. If you do this, any ValidationError raised by that
|
Form's clean() method. If you do this, any ValidationError raised by that
|
||||||
method will not be associated with a particular field; it will have a
|
method will not be associated with a particular field; it will have a
|
||||||
special-case association with the field named '__all__'.
|
special-case association with the field named '__all__'.
|
||||||
Note that in Form.clean(), you have access to self.clean_data, a dictionary of
|
Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of
|
||||||
all the fields/values that have *not* raised a ValidationError. Also note
|
all the fields/values that have *not* raised a ValidationError. Also note
|
||||||
Form.clean() is required to return a dictionary of all clean data.
|
Form.clean() is required to return a dictionary of all clean data.
|
||||||
>>> class UserRegistration(Form):
|
>>> class UserRegistration(Form):
|
||||||
|
@ -2357,9 +2357,9 @@ Form.clean() is required to return a dictionary of all clean data.
|
||||||
... password1 = CharField(widget=PasswordInput)
|
... password1 = CharField(widget=PasswordInput)
|
||||||
... password2 = CharField(widget=PasswordInput)
|
... password2 = CharField(widget=PasswordInput)
|
||||||
... def clean(self):
|
... def clean(self):
|
||||||
... if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
|
... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
|
||||||
... raise ValidationError(u'Please make sure your passwords match.')
|
... raise ValidationError(u'Please make sure your passwords match.')
|
||||||
... return self.clean_data
|
... return self.cleaned_data
|
||||||
>>> f = UserRegistration(auto_id=False)
|
>>> f = UserRegistration(auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
|
@ -2386,7 +2386,7 @@ Form.clean() is required to return a dictionary of all clean data.
|
||||||
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
|
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
|
||||||
>>> f.errors
|
>>> f.errors
|
||||||
{}
|
{}
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
|
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
|
||||||
|
|
||||||
# Dynamic construction ########################################################
|
# Dynamic construction ########################################################
|
||||||
|
@ -2954,7 +2954,7 @@ actual field name.
|
||||||
{}
|
{}
|
||||||
>>> p.is_valid()
|
>>> p.is_valid()
|
||||||
True
|
True
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
||||||
|
|
||||||
Let's try submitting some bad data to make sure form.errors and field.errors
|
Let's try submitting some bad data to make sure form.errors and field.errors
|
||||||
|
@ -2998,12 +2998,12 @@ of the same form.
|
||||||
>>> p1 = Person(data, prefix='person1')
|
>>> p1 = Person(data, prefix='person1')
|
||||||
>>> p1.is_valid()
|
>>> p1.is_valid()
|
||||||
True
|
True
|
||||||
>>> p1.clean_data
|
>>> p1.cleaned_data
|
||||||
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
||||||
>>> p2 = Person(data, prefix='person2')
|
>>> p2 = Person(data, prefix='person2')
|
||||||
>>> p2.is_valid()
|
>>> p2.is_valid()
|
||||||
True
|
True
|
||||||
>>> p2.clean_data
|
>>> p2.cleaned_data
|
||||||
{'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)}
|
{'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)}
|
||||||
|
|
||||||
By default, forms append a hyphen between the prefix and the field name, but a
|
By default, forms append a hyphen between the prefix and the field name, but a
|
||||||
|
@ -3029,7 +3029,7 @@ self.prefix.
|
||||||
>>> p = Person(data, prefix='foo')
|
>>> p = Person(data, prefix='foo')
|
||||||
>>> p.is_valid()
|
>>> p.is_valid()
|
||||||
True
|
True
|
||||||
>>> p.clean_data
|
>>> p.cleaned_data
|
||||||
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
|
||||||
|
|
||||||
# Forms with NullBooleanFields ################################################
|
# Forms with NullBooleanFields ################################################
|
||||||
|
@ -3091,16 +3091,16 @@ is different than its data. This is handled transparently, though.
|
||||||
... password1 = CharField(widget=PasswordInput)
|
... password1 = CharField(widget=PasswordInput)
|
||||||
... password2 = CharField(widget=PasswordInput)
|
... password2 = CharField(widget=PasswordInput)
|
||||||
... def clean(self):
|
... def clean(self):
|
||||||
... if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
|
... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
|
||||||
... raise ValidationError(u'Please make sure your passwords match.')
|
... raise ValidationError(u'Please make sure your passwords match.')
|
||||||
... return self.clean_data
|
... return self.cleaned_data
|
||||||
>>> def my_function(method, post_data):
|
>>> def my_function(method, post_data):
|
||||||
... if method == 'POST':
|
... if method == 'POST':
|
||||||
... form = UserRegistration(post_data, auto_id=False)
|
... form = UserRegistration(post_data, auto_id=False)
|
||||||
... else:
|
... else:
|
||||||
... form = UserRegistration(auto_id=False)
|
... form = UserRegistration(auto_id=False)
|
||||||
... if form.is_valid():
|
... if form.is_valid():
|
||||||
... return 'VALID: %r' % form.clean_data
|
... return 'VALID: %r' % form.cleaned_data
|
||||||
... t = Template('<form action="" method="post">\n<table>\n{{ form }}\n</table>\n<input type="submit" />\n</form>')
|
... t = Template('<form action="" method="post">\n<table>\n{{ form }}\n</table>\n<input type="submit" />\n</form>')
|
||||||
... return t.render(Context({'form': form}))
|
... return t.render(Context({'form': form}))
|
||||||
|
|
||||||
|
@ -3138,9 +3138,9 @@ VALID: {'username': u'adrian', 'password1': u'secret', 'password2': u'secret'}
|
||||||
... password1 = CharField(widget=PasswordInput)
|
... password1 = CharField(widget=PasswordInput)
|
||||||
... password2 = CharField(widget=PasswordInput)
|
... password2 = CharField(widget=PasswordInput)
|
||||||
... def clean(self):
|
... def clean(self):
|
||||||
... if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
|
... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
|
||||||
... raise ValidationError(u'Please make sure your passwords match.')
|
... raise ValidationError(u'Please make sure your passwords match.')
|
||||||
... return self.clean_data
|
... return self.cleaned_data
|
||||||
|
|
||||||
You have full flexibility in displaying form fields in a template. Just pass a
|
You have full flexibility in displaying form fields in a template. Just pass a
|
||||||
Form instance to the template, and use "dot" access to refer to individual
|
Form instance to the template, and use "dot" access to refer to individual
|
||||||
|
@ -3490,7 +3490,7 @@ ValidationError: [u'This field is required.']
|
||||||
</select>
|
</select>
|
||||||
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
|
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
|
||||||
|
|
||||||
>>> f.clean_data
|
>>> f.cleaned_data
|
||||||
{'field1': u'some text,JP,2007-04-25 06:24:00'}
|
{'field1': u'some text,JP,2007-04-25 06:24:00'}
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
|
|
Loading…
Reference in New Issue