1
0
mirror of https://github.com/django/django.git synced 2025-07-07 19:29:12 +00:00

[soc2009/model-validation] Update the validation docs to reflect new order of things

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11433 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Honza Král 2009-08-11 17:19:48 +00:00
parent 45112c21a6
commit 8c98833283

View File

@ -26,28 +26,14 @@ Most validation can be done using `validators`_ - simple helpers that can be
reused easily. There are two types of validators: reused easily. There are two types of validators:
* Simple validators are simple functions (or callables) that take a single * Simple validators are simple functions (or callables) that take a single
argument and raises ``ValidationError`` on invalid input:: argument and raises ``ValidationError`` on invalid input. Simple
validators are run inside the ``run_validators`` method that is called
def validate_answer_to_life_universe_and_everything(value): from ``Field.clean`` once the value is validated by the field's methods.
if value != '42':
raise ValidationError(
'This is not the answer to life, universe and everything!')
Simple validators are run inside the ``run_validators`` method that is
called from ``Field.clean`` once the value is validated by the field's
methods.
* Complex validators are instances of ``ComplexValidator`` class and, * Complex validators are instances of ``ComplexValidator`` class and,
unlike simple validators, can access not just one value, but all at once:: unlike simple validators, can access not just one value, but all at once.
These are perfectly suited for cross field validation (one of N fields
class ValidateFieldNotEqualsOtherField(ComplexValidator): must be supplied, this field must equal that etc.)
def __init__(self, other_field):
self.other_field = other_field
def __call__(self, value, all_values={}, obj=None):
if value == self.get_value(self.other_field, all_values, obj):
raise ValidationError(
"Must not equal to %r's value" % self.other_field)
.. warning:: .. warning::
@ -209,35 +195,61 @@ Using validators
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
.. versionadded:: .. versionadded::
Django's form- (and model-) fields support use of simple uitility functions and
classes known as validators. These can be added to fields on their declaration
as argument to ``__init__`` or defined on the Field class itself.
Simple validators can be used to validate values inside the field, let's have a
look at Django's ``EmailField``::
class EmailField(CharField):
default_error_messages = {
'invalid': _(u'Enter a valid e-mail address.'),
}
default_validators = [validators.validate_email]
As you can see, ``EmailField`` is just a ``CharField`` with customized error
message and a validator that validates e-mail addresses. This can also be done on field definition so::
email = forms.EmailField()
is equivalent to::
email = forms.CharField(
error_messages={
'invalid': _(u'Enter a valid e-mail address.'),
},
validators=[validators.validate_email]
)
Form field default cleaning Form field default cleaning
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's firstly create a custom form field that validates its input is a string Let's firstly create a custom form field that validates its input is a string
containing comma-separated e-mail addresses, with at least one address. We'll containing comma-separated e-mail addresses, with at least one address. The
keep it simple and assume e-mail validation is contained in a function called full class looks like this::
``is_valid_email()``. The full class looks like this::
from django import forms from django import forms
from django.core.validators import validate_email
class MultiEmailField(forms.Field): class MultiEmailField(forms.Field):
def clean(self, value): def to_python(self, value):
""" "Normalize data to a list of strings."
Check that the field contains one or more comma-separated emails return value.split(',')
and normalizes the data to a list of the email strings.
"""
if not value:
raise forms.ValidationError('Enter at least one e-mail address.')
emails = value.split(',')
for email in emails:
if not is_valid_email(email):
raise forms.ValidationError('%s is not a valid e-mail address.' % email)
# Always return the cleaned data. def validate(self, value):
return emails "Check if value consists only of valid emails."
Every form that uses this field will have this ``clean()`` method run before # check if value is given if the field is required
anything else can be done with the field's data. This is cleaning that is super(MultiEmailField, self).validate()
specific to this type of field, regardless of how it is subsequently used.
for email in value:
validate_email(email)
Every form that uses this field will have these methods run before anything
else can be done with the field's data. This is cleaning that is specific to
this type of field, regardless of how it is subsequently used.
Let's create a simple ``ContactForm`` to demonstrate how you'd use this Let's create a simple ``ContactForm`` to demonstrate how you'd use this
field:: field::
@ -251,7 +263,8 @@ field::
Simply use ``MultiEmailField`` like any other form field. When the Simply use ``MultiEmailField`` like any other form field. When the
``is_valid()`` method is called on the form, the ``MultiEmailField.clean()`` ``is_valid()`` method is called on the form, the ``MultiEmailField.clean()``
method will be run as part of the cleaning process. method will be run as part of the cleaning process and it will, in turn, call
the custom ``to_python()`` and ``validate()`` methods.
Cleaning a specific field attribute Cleaning a specific field attribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~