Index: newforms.txt
===================================================================
--- newforms.txt	(revision 5422)
+++ newforms.txt	(working copy)
@@ -1201,6 +1201,73 @@
 ``clean()`` method and that its ``__init__()`` method accept the core arguments
 mentioned above (``required``, ``label``, ``initial``, ``widget``,
 ``help_text``).
+
+``Adding custom validation to forms``
+-------------------------------------
+
+Validation is tied to the process of cleaning the data when it is processed
+in the forms. There are three types of cleaning methods that are run during form
+processing. These are all executed when you access Form.errors or call
+call Form.full_clean() explicitly (or by using Form.is_valid(), which accesses
+Form.errors).
+
+In general, any cleaning method can raise ValidationError if there is 
+a problem with the data it is processing, passing the relevant error
+message to the ValidationError's constructor. If no ValidationError is
+raised, the method should return a Python object for the cleaned
+(normalised) data.
+
+The three types of methods are:
+
+    * The clean() method on a Field subclass. This is responsible
+      for cleaning the data in a way that is generic for that type of
+      field. For example, a FloatField will turn the data into a
+      Python float or raise a ValidationError.
+
+    * The clean_fieldname() method in a form subclass -- where "fieldname" is
+      replaced with the name of the form field attribute. This method
+      does any cleaning that is specific to that particular attribute,
+      unrelated to the type of field that it is. For example, if you 
+      wanted to validate that the contents of a CharField called "serialnumber"
+      was unique, clean_serialnumber() would be the right place to do 
+      uniqueness validation. You don't need a specific field (it's just 
+      a CharField) -- but you want a formfield-specific piece of validation
+      and, possibly, cleaning/normalizing the data (making sure it's all lower
+      or upper case for example).
+
+    * The Form subclass's clean() method. This method can perform
+      any validation that requires access to multiple fields from the
+      form at once. This is where you might put in things to check
+      that if field A is supplied, field B must contain a valid email
+      address and the like. The data that this method returns is the
+      final cleaned_data attribute for the form, so don't forget to
+      return the full list of cleaned data if you override this method
+      (by default, Form.clean() just returns self.cleaned_data).
+
+      Note that any errors raised by your Form.clean() override will
+      not be associated with any field in particular. They go into a
+      special "field" called "__all__", which you can access via
+      Form.non_field_errors() if you need to.
+
+These methods are run in the order given above, one field at a time.
+That is, for each field in the form (in the order they are declared in
+the form definition), the Field.clean() method (or it's override) is
+run, then clean_<fieldname>(). Finally, once those two methods are run
+for every field, the Form.clean() method, or it's override, is executed.
+
+Again, any of these methods can raise a ValidationError. For any field,
+if step (1) raises a ValidationError, step (2) is not run, however,
+steps (1) and (2) are run for all remaining fields. Regardless of the
+results of steps (1) and (2), step (3) is always run. If step (3) raises
+a ValidationError, self.cleaned_data will be an empty dictionary.
+
+The previous paragraph means that if you are overriding Form.clean(),
+you should iterate through self.cleaned_data.items(), rather than
+through the list of fields in the forms: not every field may end up
+contributing to cleaned_data, because they may have raised
+ValidationErrors themselves, so don't assume you have the data you need
+by accessing the form fields directly -- always talk to
+self.cleaned_data.
 
 Generating forms for models
 ===========================
