Sophie

Sophie

distrib > Arklinux > devel > i586 > media > main > by-pkgid > 5fcb1fedf34660bc240dc59b7bfcebc4 > files > 384

django-doc-1.2.3-1ark.noarch.rpm


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Form and field validation &mdash; Django v1.2 documentation</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../',
        VERSION:     '1.2',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <link rel="top" title="Django v1.2 documentation" href="../../index.html" />
    <link rel="up" title="Forms" href="index.html" />
    <link rel="next" title="Generic views" href="../generic-views.html" />
    <link rel="prev" title="Widgets" href="widgets.html" />
 
<script type="text/javascript" src="../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);
</script>

  </head>
  <body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django v1.2 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="widgets.html" title="Widgets">previous</a> 
     |
    <a href="../index.html" title="API Reference" accesskey="U">up</a>
   |
    <a href="../generic-views.html" title="Generic views">next</a> &raquo;</div>
    </div>
    
    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="ref-forms-validation">
            
  <div class="section" id="s-form-and-field-validation">
<span id="form-and-field-validation"></span><h1>Form and field validation<a class="headerlink" href="#form-and-field-validation" title="Permalink to this headline">¶</a></h1>
<div class="versionchanged">
<span class="title">Changed in Django 1.2:</span> <a class="reference internal" href="../../releases/1.2.html"><em>Please, see the release notes</em></a></div>
<p>Form validation happens when the data is cleaned. If you want to customize
this process, there are various places you can change, each one serving a
different purpose. Three types of cleaning methods are run during form
processing. These are normally executed when you call the <tt class="docutils literal"><span class="pre">is_valid()</span></tt>
method on a form. There are other things that can trigger cleaning and
validation (accessing the <tt class="docutils literal"><span class="pre">errors</span></tt> attribute or calling <tt class="docutils literal"><span class="pre">full_clean()</span></tt>
directly), but normally they won&#8217;t be needed.</p>
<p>In general, any cleaning method can raise <tt class="docutils literal"><span class="pre">ValidationError</span></tt> if there is a
problem with the data it is processing, passing the relevant error message to
the <tt class="docutils literal"><span class="pre">ValidationError</span></tt> constructor. If no <tt class="docutils literal"><span class="pre">ValidationError</span></tt> is raised, the
method should return the cleaned (normalized) data as a Python object.</p>
<p>If you detect multiple errors during a cleaning method and wish to signal all
of them to the form submitter, it is possible to pass a list of errors to the
<tt class="docutils literal"><span class="pre">ValidationError</span></tt> constructor.</p>
<p>Most validation can be done using <a class="reference internal" href="#validators">validators</a> - simple helpers that can be
reused easily. Validators are simple functions (or callables) that take a single
argument and raise <tt class="docutils literal"><span class="pre">ValidationError</span></tt> on invalid input. Validators are run
after the field&#8217;s <tt class="docutils literal"><span class="pre">to_python</span></tt> and <tt class="docutils literal"><span class="pre">validate</span></tt> methods have been called.</p>
<p>Validation of a Form is split into several steps, which can be customized or
overridden:</p>
<ul>
<li><p class="first">The <tt class="docutils literal"><span class="pre">to_python()</span></tt> method on a Field is the first step in every
validation. It coerces the value to correct datatype and raises
<tt class="docutils literal"><span class="pre">ValidationError</span></tt> if that is not possible. This method accepts the raw
value from the widget and returns the converted value. For example, a
FloatField will turn the data into a Python <tt class="docutils literal"><span class="pre">float</span></tt> or raise a
<tt class="docutils literal"><span class="pre">ValidationError</span></tt>.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">validate()</span></tt> method on a Field handles field-specific validation
that is not suitable for a validator, It takes a value that has been
coerced to correct datatype and raises <tt class="docutils literal"><span class="pre">ValidationError</span></tt> on any error.
This method does not return anything and shouldn&#8217;t alter the value. You
should override it to handle validation logic that you can&#8217;t or don&#8217;t
want to put in a validator.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">run_validators()</span></tt> method on a Field runs all of the field&#8217;s
validators and aggregates all the errors into a single
<tt class="docutils literal"><span class="pre">ValidationError</span></tt>. You shouldn&#8217;t need to override this method.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">clean()</span></tt> method on a Field subclass. This is responsible for
running <tt class="docutils literal"><span class="pre">to_python</span></tt>, <tt class="docutils literal"><span class="pre">validate</span></tt> and <tt class="docutils literal"><span class="pre">run_validators</span></tt> in the correct
order and propagating their errors. If, at any time, any of the methods
raise <tt class="docutils literal"><span class="pre">ValidationError</span></tt>, the validation stops and that error is raised.
This method returns the clean data, which is then inserted into the
<tt class="docutils literal"><span class="pre">cleaned_data</span></tt> dictionary of the form.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">clean_&lt;fieldname&gt;()</span></tt> method in a form subclass &#8211; where
<tt class="docutils literal"><span class="pre">&lt;fieldname&gt;</span></tt> 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. This method is not
passed any parameters. You will need to look up the value of the field
in <tt class="docutils literal"><span class="pre">self.cleaned_data</span></tt> and remember that it will be a Python object
at this point, not the original string submitted in the form (it will be
in <tt class="docutils literal"><span class="pre">cleaned_data</span></tt> because the general field <tt class="docutils literal"><span class="pre">clean()</span></tt> method, above,
has already cleaned the data once).</p>
<p>For example, if you wanted to validate that the contents of a
<tt class="docutils literal"><span class="pre">CharField</span></tt> called <tt class="docutils literal"><span class="pre">serialnumber</span></tt> was unique,
<tt class="docutils literal"><span class="pre">clean_serialnumber()</span></tt> would be the right place to do this. You don&#8217;t
need a specific field (it&#8217;s just a <tt class="docutils literal"><span class="pre">CharField</span></tt>), but you want a
formfield-specific piece of validation and, possibly,
cleaning/normalizing the data.</p>
<p>Just like the general field <tt class="docutils literal"><span class="pre">clean()</span></tt> method, above, this method
should return the cleaned data, regardless of whether it changed
anything or not.</p>
</li>
<li><p class="first">The Form subclass&#8217;s <tt class="docutils literal"><span class="pre">clean()</span></tt> 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 <tt class="docutils literal"><span class="pre">A</span></tt>
is supplied, field <tt class="docutils literal"><span class="pre">B</span></tt> must contain a valid e-mail address and the
like. The data that this method returns is the final <tt class="docutils literal"><span class="pre">cleaned_data</span></tt>
attribute for the form, so don&#8217;t forget to return the full list of
cleaned data if you override this method (by default, <tt class="docutils literal"><span class="pre">Form.clean()</span></tt>
just returns <tt class="docutils literal"><span class="pre">self.cleaned_data</span></tt>).</p>
<p>Note that any errors raised by your <tt class="docutils literal"><span class="pre">Form.clean()</span></tt> override will not
be associated with any field in particular. They go into a special
&#8220;field&#8221; (called <tt class="docutils literal"><span class="pre">__all__</span></tt>), which you can access via the
<tt class="docutils literal"><span class="pre">non_field_errors()</span></tt> method if you need to. If you want to attach
errors to a specific field in the form, you will need to access the
<tt class="docutils literal"><span class="pre">_errors</span></tt> attribute on the form, which is <a class="reference internal" href="#described-later">described later</a>.</p>
<p>Also note that there are special considerations when overriding
the <tt class="docutils literal"><span class="pre">clean()</span></tt> method of a <tt class="docutils literal"><span class="pre">ModelForm</span></tt> subclass. (see the
<a class="reference internal" href="../../topics/forms/modelforms.html#overriding-modelform-clean-method"><em>ModelForm documentation</em></a> for more information)</p>
</li>
</ul>
<p>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 <tt class="docutils literal"><span class="pre">Field.clean()</span></tt> method (or its override) is run, then
<tt class="docutils literal"><span class="pre">clean_&lt;fieldname&gt;()</span></tt>. Finally, once those two methods are run for every
field, the <tt class="docutils literal"><span class="pre">Form.clean()</span></tt> method, or its override, is executed.</p>
<p>Examples of each of these methods are provided below.</p>
<p>As mentioned, any of these methods can raise a <tt class="docutils literal"><span class="pre">ValidationError</span></tt>. For any
field, if the <tt class="docutils literal"><span class="pre">Field.clean()</span></tt> method raises a <tt class="docutils literal"><span class="pre">ValidationError</span></tt>, any
field-specific cleaning method is not called. However, the cleaning methods
for all remaining fields are still executed.</p>
<p>The <tt class="docutils literal"><span class="pre">clean()</span></tt> method for the <tt class="docutils literal"><span class="pre">Form</span></tt> class or subclass is always run. If
that method raises a <tt class="docutils literal"><span class="pre">ValidationError</span></tt>, <tt class="docutils literal"><span class="pre">cleaned_data</span></tt> will be an empty
dictionary.</p>
<p>The previous paragraph means that if you are overriding <tt class="docutils literal"><span class="pre">Form.clean()</span></tt>, you
should iterate through <tt class="docutils literal"><span class="pre">self.cleaned_data.items()</span></tt>, possibly considering the
<tt class="docutils literal"><span class="pre">_errors</span></tt> dictionary attribute on the form as well. In this way, you will
already know which fields have passed their individual validation requirements.</p>
<div class="section" id="s-form-subclasses-and-modifying-field-errors">
<span id="s-described-later"></span><span id="form-subclasses-and-modifying-field-errors"></span><span id="described-later"></span><h2>Form subclasses and modifying field errors<a class="headerlink" href="#form-subclasses-and-modifying-field-errors" title="Permalink to this headline">¶</a></h2>
<p>Sometimes, in a form&#8217;s <tt class="docutils literal"><span class="pre">clean()</span></tt> method, you will want to add an error
message to a particular field in the form. This won&#8217;t always be appropriate
and the more typical situation is to raise a <tt class="docutils literal"><span class="pre">ValidationError</span></tt> from
<tt class="docutils literal"><span class="pre">Form.clean()</span></tt>, which is turned into a form-wide error that is available
through the <tt class="docutils literal"><span class="pre">Form.non_field_errors()</span></tt> method.</p>
<p>When you really do need to attach the error to a particular field, you should
store (or amend) a key in the <tt class="docutils literal"><span class="pre">Form._errors</span></tt> attribute. This attribute is an
instance of a <tt class="docutils literal"><span class="pre">django.forms.util.ErrorDict</span></tt> class. Essentially, though, it&#8217;s
just a dictionary. There is a key in the dictionary for each field in the form
that has an error. Each value in the dictionary is a
<tt class="docutils literal"><span class="pre">django.forms.util.ErrorList</span></tt> instance, which is a list that knows how to
display itself in different ways. So you can treat <tt class="docutils literal"><span class="pre">_errors</span></tt> as a dictionary
mapping field names to lists.</p>
<p>If you want to add a new error to a particular field, you should check whether
the key already exists in <tt class="docutils literal"><span class="pre">self._errors</span></tt> or not. If not, create a new entry
for the given key, holding an empty <tt class="docutils literal"><span class="pre">ErrorList</span></tt> instance. In either case,
you can then append your error message to the list for the field name in
question and it will be displayed when the form is displayed.</p>
<p>There is an example of modifying <tt class="docutils literal"><span class="pre">self._errors</span></tt> in the following section.</p>
<div class="admonition-what-s-in-a-name admonition ">
<p class="first admonition-title">What&#8217;s in a name?</p>
<p>You may be wondering why is this attribute called <tt class="docutils literal"><span class="pre">_errors</span></tt> and not
<tt class="docutils literal"><span class="pre">errors</span></tt>. Normal Python practice is to prefix a name with an underscore
if it&#8217;s not for external usage. In this case, you are subclassing the
<tt class="docutils literal"><span class="pre">Form</span></tt> class, so you are essentially writing new internals. In effect,
you are given permission to access some of the internals of <tt class="docutils literal"><span class="pre">Form</span></tt>.</p>
<p>Of course, any code outside your form should never access <tt class="docutils literal"><span class="pre">_errors</span></tt>
directly. The data is available to external code through the <tt class="docutils literal"><span class="pre">errors</span></tt>
property, which populates <tt class="docutils literal"><span class="pre">_errors</span></tt> before returning it).</p>
<p class="last">Another reason is purely historical: the attribute has been called
<tt class="docutils literal"><span class="pre">_errors</span></tt> since the early days of the forms module and changing it now
(particularly since <tt class="docutils literal"><span class="pre">errors</span></tt> is used for the read-only property name)
would be inconvenient for a number of reasons. You can use whichever
explanation makes you feel more comfortable. The result is the same.</p>
</div>
</div>
<div class="section" id="s-using-validation-in-practice">
<span id="using-validation-in-practice"></span><h2>Using validation in practice<a class="headerlink" href="#using-validation-in-practice" title="Permalink to this headline">¶</a></h2>
<p>The previous sections explained how validation works in general for forms.
Since it can sometimes be easier to put things into place by seeing each
feature in use, here are a series of small examples that use each of the
previous features.</p>
<div class="section" id="s-using-validators">
<span id="s-validators"></span><span id="using-validators"></span><span id="validators"></span><h3>Using validators<a class="headerlink" href="#using-validators" title="Permalink to this headline">¶</a></h3>
<div class="versionadded">
<span class="title">New in Django 1.2:</span> <a class="reference internal" href="../../releases/1.2.html"><em>Please, see the release notes</em></a></div>
<p>Django&#8217;s form (and model) fields support use of simple utility functions and
classes known as validators. These can be passed to a field&#8217;s constructor, via
the field&#8217;s <tt class="docutils literal"><span class="pre">validators</span></tt> argument, or defined on the Field class itself with
the <tt class="docutils literal"><span class="pre">default_validators</span></tt> attribute.</p>
<p>Simple validators can be used to validate values inside the field, let&#8217;s have
a look at Django&#8217;s <tt class="docutils literal"><span class="pre">EmailField</span></tt>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">EmailField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
    <span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">&#39;invalid&#39;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s">u&#39;Enter a valid e-mail address.&#39;</span><span class="p">),</span>
    <span class="p">}</span>
    <span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_email</span><span class="p">]</span>
</pre></div>
</div>
<p>As you can see, <tt class="docutils literal"><span class="pre">EmailField</span></tt> is just a <tt class="docutils literal"><span class="pre">CharField</span></tt> with customized error
message and a validator that validates e-mail addresses. This can also be done
on field definition so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">email</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">EmailField</span><span class="p">()</span>
</pre></div>
</div>
<p>is equivalent to:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">email</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">validators</span><span class="o">=</span><span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_email</span><span class="p">],</span>
        <span class="n">error_messages</span><span class="o">=</span><span class="p">{</span><span class="s">&#39;invalid&#39;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s">u&#39;Enter a valid e-mail address.&#39;</span><span class="p">)})</span>
</pre></div>
</div>
</div>
<div class="section" id="s-form-field-default-cleaning">
<span id="form-field-default-cleaning"></span><h3>Form field default cleaning<a class="headerlink" href="#form-field-default-cleaning" title="Permalink to this headline">¶</a></h3>
<p>Let's firstly create a custom form field that validates its input is a string
containing comma-separated e-mail addresses. The full class looks like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
<span class="kn">from</span> <span class="nn">django.core.validators</span> <span class="kn">import</span> <span class="n">validate_email</span>

<span class="k">class</span> <span class="nc">MultiEmailField</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Field</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="s">&quot;Normalize data to a list of strings.&quot;</span>

        <span class="c"># Return an empty list if no input was given.</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="p">:</span>
            <span class="k">return</span> <span class="p">[]</span>
        <span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;,&#39;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="s">&quot;Check if value consists only of valid emails.&quot;</span>

        <span class="c"># Use the parent&#39;s handling of required fields, etc.</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">MultiEmailField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">email</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
            <span class="n">validate_email</span><span class="p">(</span><span class="n">email</span><span class="p">)</span>
</pre></div>
</div>
<p>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.</p>
<p>Let's create a simple <tt class="docutils literal"><span class="pre">ContactForm</span></tt> to demonstrate how you'd use this
field:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">ContactForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
    <span class="n">subject</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
    <span class="n">message</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">()</span>
    <span class="n">sender</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">EmailField</span><span class="p">()</span>
    <span class="n">recipients</span> <span class="o">=</span> <span class="n">MultiEmailField</span><span class="p">()</span>
    <span class="n">cc_myself</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">BooleanField</span><span class="p">(</span><span class="n">required</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</pre></div>
</div>
<p>Simply use <tt class="docutils literal"><span class="pre">MultiEmailField</span></tt> like any other form field. When the
<tt class="docutils literal"><span class="pre">is_valid()</span></tt> method is called on the form, the <tt class="docutils literal"><span class="pre">MultiEmailField.clean()</span></tt>
method will be run as part of the cleaning process and it will, in turn, call
the custom <tt class="docutils literal"><span class="pre">to_python()</span></tt> and <tt class="docutils literal"><span class="pre">validate()</span></tt> methods.</p>
</div>
<div class="section" id="s-cleaning-a-specific-field-attribute">
<span id="cleaning-a-specific-field-attribute"></span><h3>Cleaning a specific field attribute<a class="headerlink" href="#cleaning-a-specific-field-attribute" title="Permalink to this headline">¶</a></h3>
<p>Continuing on from the previous example, suppose that in our <tt class="docutils literal"><span class="pre">ContactForm</span></tt>,
we want to make sure that the <tt class="docutils literal"><span class="pre">recipients</span></tt> field always contains the address
<tt class="docutils literal"><span class="pre">&quot;fred&#64;example.com&quot;</span></tt>. This is validation that is specific to our form, so we
don't want to put it into the general <tt class="docutils literal"><span class="pre">MultiEmailField</span></tt> class. Instead, we
write a cleaning method that operates on the <tt class="docutils literal"><span class="pre">recipients</span></tt> field, like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">ContactForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
    <span class="c"># Everything as before.</span>
    <span class="o">...</span>

    <span class="k">def</span> <span class="nf">clean_recipients</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;recipients&#39;</span><span class="p">]</span>
        <span class="k">if</span> <span class="s">&quot;fred@example.com&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">forms</span><span class="o">.</span><span class="n">ValidationError</span><span class="p">(</span><span class="s">&quot;You have forgotten about Fred!&quot;</span><span class="p">)</span>

        <span class="c"># Always return the cleaned data, whether you have changed it or</span>
        <span class="c"># not.</span>
        <span class="k">return</span> <span class="n">data</span>
</pre></div>
</div>
</div>
<div class="section" id="s-cleaning-and-validating-fields-that-depend-on-each-other">
<span id="cleaning-and-validating-fields-that-depend-on-each-other"></span><h3>Cleaning and validating fields that depend on each other<a class="headerlink" href="#cleaning-and-validating-fields-that-depend-on-each-other" title="Permalink to this headline">¶</a></h3>
<p>Suppose we add another requirement to our contact form: if the <tt class="docutils literal"><span class="pre">cc_myself</span></tt>
field is <tt class="xref docutils literal"><span class="pre">True</span></tt>, the <tt class="docutils literal"><span class="pre">subject</span></tt> must contain the word <tt class="docutils literal"><span class="pre">&quot;help&quot;</span></tt>. We are
performing validation on more than one field at a time, so the form's
<tt class="docutils literal"><span class="pre">clean()</span></tt> method is a good spot to do this. Notice that we are talking about
the <tt class="docutils literal"><span class="pre">clean()</span></tt> method on the form here, whereas earlier we were writing a
<tt class="docutils literal"><span class="pre">clean()</span></tt> method on a field. It's important to keep the field and form
difference clear when working out where to validate things. Fields are single
data points, forms are a collection of fields.</p>
<p>By the time the form's <tt class="docutils literal"><span class="pre">clean()</span></tt> method is called, all the individual field
clean methods will have been run (the previous two sections), so
<tt class="docutils literal"><span class="pre">self.cleaned_data</span></tt> will be populated with any data that has survived so
far. So you also need to remember to allow for the fact that the fields you
are wanting to validate might not have survived the initial individual field
checks.</p>
<p>There are two way to report any errors from this step. Probably the most
common method is to display the error at the top of the form. To create such
an error, you can raise a <tt class="docutils literal"><span class="pre">ValidationError</span></tt> from the <tt class="docutils literal"><span class="pre">clean()</span></tt> method. For
example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">ContactForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
    <span class="c"># Everything as before.</span>
    <span class="o">...</span>

    <span class="k">def</span> <span class="nf">clean</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">cleaned_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span>
        <span class="n">cc_myself</span> <span class="o">=</span> <span class="n">cleaned_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;cc_myself&quot;</span><span class="p">)</span>
        <span class="n">subject</span> <span class="o">=</span> <span class="n">cleaned_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;subject&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">cc_myself</span> <span class="ow">and</span> <span class="n">subject</span><span class="p">:</span>
            <span class="c"># Only do something if both fields are valid so far.</span>
            <span class="k">if</span> <span class="s">&quot;help&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">subject</span><span class="p">:</span>
                <span class="k">raise</span> <span class="n">forms</span><span class="o">.</span><span class="n">ValidationError</span><span class="p">(</span><span class="s">&quot;Did not send for &#39;help&#39; in &quot;</span>
                        <span class="s">&quot;the subject despite CC&#39;ing yourself.&quot;</span><span class="p">)</span>

        <span class="c"># Always return the full collection of cleaned data.</span>
        <span class="k">return</span> <span class="n">cleaned_data</span>
</pre></div>
</div>
<p>In this code, if the validation error is raised, the form will display an
error message at the top of the form (normally) describing the problem.</p>
<p>The second approach might involve assigning the error message to one of the
fields. In this case, let's assign an error message to both the &quot;subject&quot; and
&quot;cc_myself&quot; rows in the form display. Be careful when doing this in practice,
since it can lead to confusing form output. We're showing what is possible
here and leaving it up to you and your designers to work out what works
effectively in your particular situation. Our new code (replacing the previous
sample) looks like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">ContactForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
    <span class="c"># Everything as before.</span>
    <span class="o">...</span>

    <span class="k">def</span> <span class="nf">clean</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">cleaned_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span>
        <span class="n">cc_myself</span> <span class="o">=</span> <span class="n">cleaned_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;cc_myself&quot;</span><span class="p">)</span>
        <span class="n">subject</span> <span class="o">=</span> <span class="n">cleaned_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;subject&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">cc_myself</span> <span class="ow">and</span> <span class="n">subject</span> <span class="ow">and</span> <span class="s">&quot;help&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">subject</span><span class="p">:</span>
            <span class="c"># We know these are not in self._errors now (see discussion</span>
            <span class="c"># below).</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="s">u&quot;Must put &#39;help&#39; in subject when cc&#39;ing yourself.&quot;</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_errors</span><span class="p">[</span><span class="s">&quot;cc_myself&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_class</span><span class="p">([</span><span class="n">msg</span><span class="p">])</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_errors</span><span class="p">[</span><span class="s">&quot;subject&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_class</span><span class="p">([</span><span class="n">msg</span><span class="p">])</span>

            <span class="c"># These fields are no longer valid. Remove them from the</span>
            <span class="c"># cleaned data.</span>
            <span class="k">del</span> <span class="n">cleaned_data</span><span class="p">[</span><span class="s">&quot;cc_myself&quot;</span><span class="p">]</span>
            <span class="k">del</span> <span class="n">cleaned_data</span><span class="p">[</span><span class="s">&quot;subject&quot;</span><span class="p">]</span>

        <span class="c"># Always return the full collection of cleaned data.</span>
        <span class="k">return</span> <span class="n">cleaned_data</span>
</pre></div>
</div>
<p>As you can see, this approach requires a bit more effort, not withstanding the
extra design effort to create a sensible form display. The details are worth
noting, however. Firstly, earlier we mentioned that you might need to check if
the field name keys already exist in the <tt class="docutils literal"><span class="pre">_errors</span></tt> dictionary. In this case,
since we know the fields exist in <tt class="docutils literal"><span class="pre">self.cleaned_data</span></tt>, they must have been
valid when cleaned as individual fields, so there will be no corresponding
entries in <tt class="docutils literal"><span class="pre">_errors</span></tt>.</p>
<p>Secondly, once we have decided that the combined data in the two fields we are
considering aren't valid, we must remember to remove them from the
<tt class="docutils literal"><span class="pre">cleaned_data</span></tt>.</p>
<p>In fact, Django will currently completely wipe out the <tt class="docutils literal"><span class="pre">cleaned_data</span></tt>
dictionary if there are any errors in the form. However, this behaviour may
change in the future, so it's not a bad idea to clean up after yourself in the
first place.</p>
</div>
</div>
</div>


          </div>         
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Form and field validation</a><ul>
<li><a class="reference internal" href="#form-subclasses-and-modifying-field-errors">Form subclasses and modifying field errors</a></li>
<li><a class="reference internal" href="#using-validation-in-practice">Using validation in practice</a><ul>
<li><a class="reference internal" href="#using-validators">Using validators</a></li>
<li><a class="reference internal" href="#form-field-default-cleaning">Form field default cleaning</a></li>
<li><a class="reference internal" href="#cleaning-a-specific-field-attribute">Cleaning a specific field attribute</a></li>
<li><a class="reference internal" href="#cleaning-and-validating-fields-that-depend-on-each-other">Cleaning and validating fields that depend on each other</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h3>Browse</h3>
  <ul>
    
      <li>Prev: <a href="widgets.html">Widgets</a></li>
    
    
      <li>Next: <a href="../generic-views.html">Generic views</a></li>
    
  </ul>
  <h3>You are here:</h3>
  <ul>
      <li>
        <a href="../../index.html">Django v1.2 documentation</a>
        
          <ul><li><a href="../index.html">API Reference</a>
        
          <ul><li><a href="index.html">Forms</a>
        
        <ul><li>Form and field validation</li></ul>
        </li></ul></li></ul>
      </li>
  </ul>  

  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="../../_sources/ref/forms/validation.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Oct 20, 2010</p>
          </div> 
        
      
    </div>
    
    <div id="ft">
      <div class="nav">
    &laquo; <a href="widgets.html" title="Widgets">previous</a> 
     |
    <a href="../index.html" title="API Reference" accesskey="U">up</a>
   |
    <a href="../generic-views.html" title="Generic views">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>