1 ===============================
2 Forms, fields, and manipulators
3 ===============================
5 Forwards-compatibility note
6 ===========================
8 The legacy forms/manipulators system described in this document is going to be
9 replaced in the next Django release. If you're starting from scratch, we
10 strongly encourage you not to waste your time learning this. Instead, learn and
11 use the new `forms library`_.
13 .. _forms library: ../forms/
18 Once you've got a chance to play with Django's admin interface, you'll probably
19 wonder if the fantastic form validation framework it uses is available to user
20 code. It is, and this document explains how the framework works.
22 We'll take a top-down approach to examining Django's form validation framework,
23 because much of the time you won't need to use the lower-level APIs. Throughout
24 this document, we'll be working with the following model, a "place" object::
26 from django.db import models
32 (4, 'Secret Hideout'),
35 class Place(models.Model):
36 name = models.CharField(max_length=100)
37 address = models.CharField(max_length=100, blank=True)
38 city = models.CharField(max_length=50, blank=True)
39 state = models.USStateField()
40 zip_code = models.CharField(max_length=5, blank=True)
41 place_type = models.IntegerField(choices=PLACE_TYPES)
46 def __unicode__(self):
49 Defining the above class is enough to create an admin interface to a ``Place``,
50 but what if you want to allow public users to submit places?
52 Automatic Manipulators
53 ======================
55 The highest-level interface for object creation and modification is the
56 **automatic Manipulator** framework. An automatic manipulator is a utility
57 class tied to a given model that "knows" how to create or modify instances of
58 that model and how to validate data for the object. Automatic Manipulators come
59 in two flavors: ``AddManipulators`` and ``ChangeManipulators``. Functionally
60 they are quite similar, but the former knows how to create new instances of the
61 model, while the latter modifies existing instances. Both types of classes are
62 automatically created when you define a new class::
64 >>> from mysite.myapp.models import Place
65 >>> Place.AddManipulator
66 <class 'django.models.manipulators.AddManipulator'>
67 >>> Place.ChangeManipulator
68 <class 'django.models.manipulators.ChangeManipulator'>
70 Using the ``AddManipulator``
71 ----------------------------
73 We'll start with the ``AddManipulator``. Here's a very simple view that takes
74 POSTed data from the browser and creates a new ``Place`` object::
76 from django.shortcuts import render_to_response
77 from django.http import Http404, HttpResponse, HttpResponseRedirect
78 from django import oldforms as forms
79 from mysite.myapp.models import Place
81 def naive_create_place(request):
82 """A naive approach to creating places; don't actually use this!"""
83 # Create the AddManipulator.
84 manipulator = Place.AddManipulator()
86 # Make a copy of the POSTed data so that do_html2python can
87 # modify it in place (request.POST is immutable).
88 new_data = request.POST.copy()
90 # Convert the request data (which will all be strings) into the
91 # appropriate Python types for those fields.
92 manipulator.do_html2python(new_data)
94 # Save the new object.
95 new_place = manipulator.save(new_data)
98 return HttpResponse("Place created: %s" % new_place)
100 The ``naive_create_place`` example works, but as you probably can tell, this
101 view has a number of problems:
103 * No validation of any sort is performed. If, for example, the ``name`` field
104 isn't given in ``request.POST``, the save step will cause a database error
105 because that field is required. Ugly.
107 * Even if you *do* perform validation, there's still no way to give that
108 information to the user in any sort of useful way.
110 * You'll have to separately create a form (and view) that submits to this
111 page, which is a pain and is redundant.
113 Let's dodge these problems momentarily to take a look at how you could create a
114 view with a form that submits to this flawed creation view::
116 def naive_create_place_form(request):
117 """Simplistic place form view; don't actually use anything like this!"""
118 # Create a FormWrapper object that the template can use. Ignore
119 # the last two arguments to FormWrapper for now.
120 form = forms.FormWrapper(Place.AddManipulator(), {}, {})
121 return render_to_response('places/naive_create_form.html', {'form': form})
123 (This view, as well as all the following ones, has the same imports as in the
124 first example above.)
126 The ``forms.FormWrapper`` object is a wrapper that templates can
127 easily deal with to create forms. Here's the ``naive_create_form.html``
130 {% extends "base.html" %}
133 <h1>Create a place:</h1>
135 <form method="post" action="../do_new/">
136 <p><label for="id_name">Name:</label> {{ form.name }}</p>
137 <p><label for="id_address">Address:</label> {{ form.address }}</p>
138 <p><label for="id_city">City:</label> {{ form.city }}</p>
139 <p><label for="id_state">State:</label> {{ form.state }}</p>
140 <p><label for="id_zip_code">Zip:</label> {{ form.zip_code }}</p>
141 <p><label for="id_place_type">Place type:</label> {{ form.place_type }}</p>
142 <input type="submit" />
146 Before we get back to the problems with these naive set of views, let's go over
147 some salient points of the above template:
149 * Field "widgets" are handled for you: ``{{ form.field }}`` automatically
150 creates the "right" type of widget for the form, as you can see with the
151 ``place_type`` field above.
153 * There isn't a way just to spit out the form. You'll still need to define
154 how the form gets laid out. This is a feature: Every form should be
155 designed differently. Django doesn't force you into any type of mold.
156 If you must use tables, use tables. If you're a semantic purist, you can
157 probably find better HTML than in the above template.
159 * To avoid name conflicts, the ``id`` values of form elements take the
160 form "id_*fieldname*".
162 By creating a creation form we've solved problem number 3 above, but we still
163 don't have any validation. Let's revise the validation issue by writing a new
164 creation view that takes validation into account::
166 def create_place_with_validation(request):
167 manipulator = Place.AddManipulator()
168 new_data = request.POST.copy()
170 # Check for validation errors
171 errors = manipulator.get_validation_errors(new_data)
172 manipulator.do_html2python(new_data)
174 return render_to_response('places/errors.html', {'errors': errors})
176 new_place = manipulator.save(new_data)
177 return HttpResponse("Place created: %s" % new_place)
179 In this new version, errors will be found -- ``manipulator.get_validation_errors``
180 handles all the validation for you -- and those errors can be nicely presented
181 on an error page (templated, of course)::
183 {% extends "base.html" %}
187 <h1>Please go back and correct the following error{{ errors|pluralize }}:</h1>
189 {% for e in errors.items %}
190 <li>Field "{{ e.0 }}": {{ e.1|join:", " }}</li>
196 Still, this has its own problems:
198 * There's still the issue of creating a separate (redundant) view for the
201 * Errors, though nicely presented, are on a separate page, so the user will
202 have to use the "back" button to fix errors. That's ridiculous and unusable.
204 The best way to deal with these issues is to collapse the two views -- the form
205 and the submission -- into a single view. This view will be responsible for
206 creating the form, validating POSTed data, and creating the new object (if the
207 data is valid). An added bonus of this approach is that errors and the form will
208 both be available on the same page, so errors with fields can be presented in
211 .. admonition:: Philosophy:
213 Finally, for the HTTP purists in the audience (and the authorship), this
214 nicely matches the "true" meanings of HTTP GET and HTTP POST: GET fetches
215 the form, and POST creates the new object.
217 Below is the finished view::
219 def create_place(request):
220 manipulator = Place.AddManipulator()
222 if request.method == 'POST':
223 # If data was POSTed, we're trying to create a new Place.
224 new_data = request.POST.copy()
227 errors = manipulator.get_validation_errors(new_data)
228 manipulator.do_html2python(new_data)
231 # No errors. This means we can save the data!
232 new_place = manipulator.save(new_data)
234 # Redirect to the object's "edit" page. Always use a redirect
235 # after POST data, so that reloads don't accidently create
236 # duplicate entires, and so users don't see the confusing
237 # "Repost POST data?" alert box in their browsers.
238 return HttpResponseRedirect("/places/edit/%i/" % new_place.id)
240 # No POST, so we want a brand new form without any data or errors.
241 errors = new_data = {}
243 # Create the FormWrapper, template, context, response.
244 form = forms.FormWrapper(manipulator, new_data, errors)
245 return render_to_response('places/create_form.html', {'form': form})
247 and here's the ``create_form`` template::
249 {% extends "base.html" %}
252 <h1>Create a place:</h1>
254 {% if form.has_errors %}
255 <h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
258 <form method="post" action=".">
260 <label for="id_name">Name:</label> {{ form.name }}
261 {% if form.name.errors %}*** {{ form.name.errors|join:", " }}{% endif %}
264 <label for="id_address">Address:</label> {{ form.address }}
265 {% if form.address.errors %}*** {{ form.address.errors|join:", " }}{% endif %}
268 <label for="id_city">City:</label> {{ form.city }}
269 {% if form.city.errors %}*** {{ form.city.errors|join:", " }}{% endif %}
272 <label for="id_state">State:</label> {{ form.state }}
273 {% if form.state.errors %}*** {{ form.state.errors|join:", " }}{% endif %}
276 <label for="id_zip_code">Zip:</label> {{ form.zip_code }}
277 {% if form.zip_code.errors %}*** {{ form.zip_code.errors|join:", " }}{% endif %}
280 <label for="id_place_type">Place type:</label> {{ form.place_type }}
281 {% if form.place_type.errors %}*** {{ form.place_type.errors|join:", " }}{% endif %}
283 <input type="submit" />
287 The second two arguments to ``FormWrapper`` (``new_data`` and ``errors``)
288 deserve some mention.
290 The first is any "default" data to be used as values for the fields. Pulling
291 the data from ``request.POST``, as is done above, makes sure that if there are
292 errors, the values the user put in aren't lost. If you try the above example,
293 you'll see this in action.
295 The second argument is the error list retrieved from
296 ``manipulator.get_validation_errors``. When passed into the ``FormWrapper``,
297 this gives each field an ``errors`` item (which is a list of error messages
298 associated with the field) as well as a ``html_error_list`` item, which is a
299 ``<ul>`` of error messages. The above template uses these error items to
300 display a simple error message next to each field. The error list is saved as
301 an ``error_dict`` attribute of the ``FormWrapper`` object.
303 Using the ``ChangeManipulator``
304 -------------------------------
306 The above has covered using the ``AddManipulator`` to create a new object. What
307 about editing an existing one? It's shockingly similar to creating a new one::
309 def edit_place(request, place_id):
310 # Get the place in question from the database and create a
311 # ChangeManipulator at the same time.
313 manipulator = Place.ChangeManipulator(place_id)
314 except Place.DoesNotExist:
317 # Grab the Place object in question for future use.
318 place = manipulator.original_object
320 if request.method == 'POST':
321 new_data = request.POST.copy()
322 errors = manipulator.get_validation_errors(new_data)
323 manipulator.do_html2python(new_data)
325 manipulator.save(new_data)
327 # Do a post-after-redirect so that reload works, etc.
328 return HttpResponseRedirect("/places/edit/%i/" % place.id)
331 # This makes sure the form accurate represents the fields of the place.
332 new_data = manipulator.flatten_data()
334 form = forms.FormWrapper(manipulator, new_data, errors)
335 return render_to_response('places/edit_form.html', {'form': form, 'place': place})
337 The only real differences are:
339 * We create a ``ChangeManipulator`` instead of an ``AddManipulator``.
340 The argument to a ``ChangeManipulator`` is the ID of the object
341 to be changed. As you can see, the initializer will raise an
342 ``ObjectDoesNotExist`` exception if the ID is invalid.
344 * ``ChangeManipulator.original_object`` stores the instance of the
347 * We set ``new_data`` based upon ``flatten_data()`` from the manipulator.
348 ``flatten_data()`` takes the data from the original object under
349 manipulation, and converts it into a data dictionary that can be used
350 to populate form elements with the existing values for the object.
352 * The above example uses a different template, so create and edit can be
353 "skinned" differently if needed, but the form chunk itself is completely
354 identical to the one in the create form above.
356 The astute programmer will notice the add and create functions are nearly
357 identical and could in fact be collapsed into a single view. This is left as an
358 exercise for said programmer.
360 (However, the even-more-astute programmer will take heed of the note at the top
361 of this document and check out the `generic views`_ documentation if all she
362 wishes to do is this type of simple create/update.)
364 Custom forms and manipulators
365 =============================
367 All the above is fine and dandy if you just want to use the automatically
368 created manipulators. But the coolness doesn't end there: You can easily create
369 your own custom manipulators for handling custom forms.
371 Custom manipulators are pretty simple. Here's a manipulator that you might use
372 for a "contact" form on a website::
374 from django import oldforms as forms
377 (1, "Extremely urgent"),
383 class ContactManipulator(forms.Manipulator):
386 forms.EmailField(field_name="from", is_required=True),
387 forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
388 forms.SelectField(field_name="urgency", choices=urgency_choices),
389 forms.LargeTextField(field_name="contents", is_required=True),
392 A certain similarity to Django's models should be apparent. The only required
393 method of a custom manipulator is ``__init__`` which must define the fields
394 present in the manipulator. See the ``django.forms`` module for
395 all the form fields provided by Django.
397 You use this custom manipulator exactly as you would use an auto-generated one.
398 Here's a simple function that might drive the above form::
400 def contact_form(request):
401 manipulator = ContactManipulator()
402 if request.method == 'POST':
403 new_data = request.POST.copy()
404 errors = manipulator.get_validation_errors(new_data)
405 manipulator.do_html2python(new_data)
408 # Send e-mail using new_data here...
410 return HttpResponseRedirect("/contact/thankyou/")
412 errors = new_data = {}
413 form = forms.FormWrapper(manipulator, new_data, errors)
414 return render_to_response('contact_form.html', {'form': form})
416 Implementing ``flatten_data`` for custom manipulators
417 ------------------------------------------------------
419 It is possible (although rarely needed) to replace the default automatically
420 created manipulators on a model with your own custom manipulators. If you do
421 this and you are intending to use those models in generic views, you should
422 also define a ``flatten_data`` method in any ``ChangeManipulator`` replacement.
423 This should act like the default ``flatten_data`` and return a dictionary
424 mapping field names to their values, like so::
426 def flatten_data(self):
427 obj = self.original_object
430 subject = obj.subject,
434 In this way, your new change manipulator will act exactly like the default
437 ``FileField`` and ``ImageField`` special cases
438 ==============================================
440 Dealing with ``FileField`` and ``ImageField`` objects is a little more
443 First, you'll need to make sure that your ``<form>`` element correctly defines
444 the ``enctype`` as ``"multipart/form-data"``, in order to upload files::
446 <form enctype="multipart/form-data" method="post" action="/foo/">
448 Next, you'll need to treat the field in the template slightly differently. A
449 ``FileField`` or ``ImageField`` is represented by *two* HTML form elements.
451 For example, given this field in a model::
453 photo = model.ImageField('/path/to/upload/location')
455 You'd need to display two formfields in the template::
457 <p><label for="id_photo">Photo:</label> {{ form.photo }}{{ form.photo_file }}</p>
459 The first bit (``{{ form.photo }}``) displays the currently-selected file,
460 while the second (``{{ form.photo_file }}``) actually contains the file upload
461 form field. Thus, at the validation layer you need to check the ``photo_file``
464 Finally, in your view, make sure to access ``request.FILES``, rather than
465 ``request.POST``, for the uploaded files. This is necessary because
466 ``request.POST`` does not contain file-upload data.
468 For example, following the ``new_data`` convention, you might do something like
471 new_data = request.POST.copy()
472 new_data.update(request.FILES)
477 One useful feature of manipulators is the automatic validation. Validation is
478 done using a simple validation API: A validator is a callable that raises a
479 ``ValidationError`` if there's something wrong with the data.
480 ``django.core.validators`` defines a host of validator functions (see below),
481 but defining your own couldn't be easier::
483 from django.core import validators
484 from django import oldforms as forms
486 class ContactManipulator(forms.Manipulator):
489 # ... snip fields as above ...
490 forms.EmailField(field_name="to", validator_list=[self.isValidToAddress])
493 def isValidToAddress(self, field_data, all_data):
494 if not field_data.endswith("@example.com"):
495 raise validators.ValidationError("You can only send messages to example.com e-mail addresses.")
497 Above, we've added a "to" field to the contact form, but required that the "to"
498 address end with "@example.com" by adding the ``isValidToAddress`` validator to
499 the field's ``validator_list``.
501 The arguments to a validator function take a little explanation. ``field_data``
502 is the value of the field in question, and ``all_data`` is a dictionary of all
503 the data being validated.
505 .. admonition:: Note::
507 At the point validators are called all data will still be
508 strings (as ``do_html2python`` hasn't been called yet).
510 Also, because consistency in user interfaces is important, we strongly urge you
511 to put punctuation at the end of your validation messages.
513 When are validators called?
514 ---------------------------
516 After a form has been submitted, Django validates each field in turn. First,
517 if the field is required, Django checks that it is present and non-empty. Then,
518 if that test passes *and the form submission contained data* for that field, all
519 the validators for that field are called in turn. The emphasized portion in the
520 last sentence is important: if a form field is not submitted (because it
521 contains no data -- which is normal HTML behavior), the validators are not
522 run against the field.
524 This feature is particularly important for models using
525 ``models.BooleanField`` or custom manipulators using things like
526 ``forms.CheckBoxField``. If the checkbox is not selected, it will not
527 contribute to the form submission.
529 If you would like your validator to run *always*, regardless of whether its
530 attached field contains any data, set the ``always_test`` attribute on the
531 validator function. For example::
533 def my_custom_validator(field_data, all_data):
535 my_custom_validator.always_test = True
537 This validator will always be executed for any field it is attached to.
539 Ready-made validators
540 ---------------------
542 Writing your own validator is not difficult, but there are some situations
543 that come up over and over again. Django comes with a number of validators
544 that can be used directly in your code. All of these functions and classes
545 reside in ``django/core/validators.py``.
547 The following validators should all be self-explanatory. Each one provides a
548 check for the given property:
555 * isCommaSeparatedIntegerList
556 * isCommaSeparatedEmailList
570 * isValidQuicktimeVideoURL
574 * isWellFormedXmlFragment
579 There are also a group of validators that are slightly more flexible. For
580 these validators, you create a validator instance, passing in the parameters
581 described below. The returned object is a callable that can be used as a
586 from django.core import validators
587 from django import oldforms as forms
589 power_validator = validators.IsAPowerOf(2)
591 class InstallationManipulator(forms.Manipulator)
595 forms.IntegerField(field_name = "size", validator_list=[power_validator])
598 Here, ``validators.IsAPowerOf(...)`` returned something that could be used as
599 a validator (in this case, a check that a number was a power of 2).
601 Each of the standard validators that take parameters have an optional final
602 argument (``error_message``) that is the message returned when validation
603 fails. If no message is passed in, a default message is used.
605 ``AlwaysMatchesOtherField``
606 Takes a field name and the current field is valid if and only if its value
607 matches the contents of the other field.
609 ``ValidateIfOtherFieldEquals``
610 Takes three parameters: ``other_field``, ``other_value`` and
611 ``validator_list``, in that order. If ``other_field`` has a value of
612 ``other_value``, then the validators in ``validator_list`` are all run
613 against the current field.
615 ``RequiredIfOtherFieldGiven``
616 Takes a field name of the current field is only required if the other
619 ``RequiredIfOtherFieldsGiven``
620 Similar to ``RequiredIfOtherFieldGiven``, except that it takes a list of
621 field names and if any one of the supplied fields has a value provided,
622 the current field being validated is required.
624 ``RequiredIfOtherFieldNotGiven``
625 Takes the name of the other field and this field is only required if the
626 other field has no value.
628 ``RequiredIfOtherFieldEquals`` and ``RequiredIfOtherFieldDoesNotEqual``
629 Each of these validator classes takes a field name and a value (in that
630 order). If the given field does (or does not have, in the latter case) the
631 given value, then the current field being validated is required.
633 An optional ``other_label`` argument can be passed which, if given, is used
634 in error messages instead of the value. This allows more user friendly error
635 messages if the value itself is not descriptive enough.
637 Note that because validators are called before any ``do_html2python()``
638 functions, the value being compared against is a string. So
639 ``RequiredIfOtherFieldEquals('choice', '1')`` is correct, whilst
640 ``RequiredIfOtherFieldEquals('choice', 1)`` will never result in the
641 equality test succeeding.
643 ``IsLessThanOtherField``
644 Takes a field name and validates that the current field being validated
645 has a value that is less than (or equal to) the other field's value.
646 Again, comparisons are done using strings, so be cautious about using
647 this function to compare data that should be treated as another type. The
648 string "123" is less than the string "2", for example. If you don't want
649 string comparison here, you will need to write your own validator.
652 Takes two boundary numbers, ``lower`` and ``upper``, and checks that the
653 field is greater than ``lower`` (if given) and less than ``upper`` (if
656 Both checks are inclusive. That is, ``NumberIsInRange(10, 20)`` will allow
657 values of both 10 and 20. This validator only checks numeric values
658 (e.g., float and integer values).
661 Takes an integer argument and when called as a validator, checks that the
662 field being validated is a power of the integer.
665 Takes a maximum number of digits and number of decimal places (in that
666 order) and validates whether the field is a decimal with no more than the
667 maximum number of digits and decimal places.
669 ``MatchesRegularExpression``
670 Takes a regular expression (a string) as a parameter and validates the
671 field value against it.
674 Takes a list of validators as a parameter. At validation time, if the
675 field successfully validates against any one of the validators, it passes
676 validation. The validators are tested in the order specified in the
680 Used to validate URL fields. Takes a list of MIME types (such as
681 ``text/plain``) at creation time. At validation time, it verifies that the
682 field is indeed a URL and then tries to retrieve the content at the URL.
683 Validation succeeds if the content could be retrieved and it has a content
684 type from the list used to create the validator.
687 Used to validate an XML document against a Relax NG compact schema. Takes
688 a file path to the location of the schema and an optional root element
689 (which is wrapped around the XML fragment before validation, if supplied).
690 At validation time, the XML fragment is validated against the schema using
691 the executable specified in the ``JING_PATH`` setting (see the settings_
692 document for more details).
694 .. _`generic views`: ../generic_views/
695 .. _`models API`: ../model-api/
696 .. _settings: ../settings/