Fixed #8267: Corrected documentation for default value of DEFAULT_FILE_STORAGE setting
[django.git] / docs / oldforms.txt
blob7703483f5d0caf4b9f7da0727a8b024277b62496
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/
15 Introduction
16 ============
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
28     PLACE_TYPES = (
29         (1, 'Bar'),
30         (2, 'Restaurant'),
31         (3, 'Movie Theater'),
32         (4, 'Secret Hideout'),
33     )
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)
43         class Admin:
44             pass
46         def __unicode__(self):
47             return self.name
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)
97         # It worked!
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``
128 template::
130     {% extends "base.html" %}
132     {% block content %}
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" />
143     </form>
144     {% endblock %}
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)
173         if errors:
174             return render_to_response('places/errors.html', {'errors': errors})
175         else:
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" %}
185     {% block content %}
187     <h1>Please go back and correct the following error{{ errors|pluralize }}:</h1>
188     <ul>
189         {% for e in errors.items %}
190         <li>Field "{{ e.0 }}": {{ e.1|join:", " }}</li>
191         {% endfor %}
192     </ul>
194     {% endblock %}
196 Still, this has its own problems:
198     * There's still the issue of creating a separate (redundant) view for the
199       submission form.
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
209 context.
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()
226             # Check for errors.
227             errors = manipulator.get_validation_errors(new_data)
228             manipulator.do_html2python(new_data)
230             if not errors:
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)
239         else:
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" %}
251     {% block content %}
252     <h1>Create a place:</h1>
254     {% if form.has_errors %}
255     <h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
256     {% endif %}
258     <form method="post" action=".">
259     <p>
260         <label for="id_name">Name:</label> {{ form.name }}
261         {% if form.name.errors %}*** {{ form.name.errors|join:", " }}{% endif %}
262     </p>
263     <p>
264         <label for="id_address">Address:</label> {{ form.address }}
265         {% if form.address.errors %}*** {{ form.address.errors|join:", " }}{% endif %}
266     </p>
267     <p>
268         <label for="id_city">City:</label> {{ form.city }}
269         {% if form.city.errors %}*** {{ form.city.errors|join:", " }}{% endif %}
270     </p>
271     <p>
272         <label for="id_state">State:</label> {{ form.state }}
273         {% if form.state.errors %}*** {{ form.state.errors|join:", " }}{% endif %}
274     </p>
275     <p>
276         <label for="id_zip_code">Zip:</label> {{ form.zip_code }}
277         {% if form.zip_code.errors %}*** {{ form.zip_code.errors|join:", " }}{% endif %}
278     </p>
279     <p>
280         <label for="id_place_type">Place type:</label> {{ form.place_type }}
281         {% if form.place_type.errors %}*** {{ form.place_type.errors|join:", " }}{% endif %}
282     </p>
283     <input type="submit" />
284     </form>
285     {% endblock %}
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.
312         try:
313             manipulator = Place.ChangeManipulator(place_id)
314         except Place.DoesNotExist:
315             raise Http404
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)
324             if not errors:
325                 manipulator.save(new_data)
327                 # Do a post-after-redirect so that reload works, etc.
328                 return HttpResponseRedirect("/places/edit/%i/" % place.id)
329         else:
330             errors = {}
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
345       object being edited.
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
376     urgency_choices = (
377         (1, "Extremely urgent"),
378         (2, "Urgent"),
379         (3, "Normal"),
380         (4, "Unimportant"),
381     )
383     class ContactManipulator(forms.Manipulator):
384         def __init__(self):
385             self.fields = (
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),
390             )
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)
406             if not errors:
408                 # Send e-mail using new_data here...
410                 return HttpResponseRedirect("/contact/thankyou/")
411         else:
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
428         return dict(
429             from = obj.from,
430             subject = obj.subject,
431             ...
432         )
434 In this way, your new change manipulator will act exactly like the default
435 version.
437 ``FileField`` and ``ImageField`` special cases
438 ==============================================
440 Dealing with ``FileField`` and ``ImageField`` objects is a little more
441 complicated.
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``
462 key.
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
469 this::
471    new_data = request.POST.copy()
472    new_data.update(request.FILES)
474 Validators
475 ==========
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):
487         def __init__(self):
488             self.fields = (
489                 # ... snip fields as above ...
490                 forms.EmailField(field_name="to", validator_list=[self.isValidToAddress])
491             )
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):
534         # ...
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:
550     * isAlphaNumeric
551     * isAlphaNumericURL
552     * isSlug
553     * isLowerCase
554     * isUpperCase
555     * isCommaSeparatedIntegerList
556     * isCommaSeparatedEmailList
557     * isValidIPAddress4
558     * isNotEmpty
559     * isOnlyDigits
560     * isNotOnlyDigits
561     * isInteger
562     * isOnlyLetters
563     * isValidANSIDate
564     * isValidANSITime
565     * isValidEmail
566     * isValidFloat
567     * isValidImage
568     * isValidImageURL
569     * isValidPhone
570     * isValidQuicktimeVideoURL
571     * isValidURL
572     * isValidHTML
573     * isWellFormedXml
574     * isWellFormedXmlFragment
575     * isExistingURL
576     * isValidUSState
577     * hasNoProfanities
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
582 validator.
584 For example::
586     from django.core import validators
587     from django import oldforms as forms
589     power_validator = validators.IsAPowerOf(2)
591     class InstallationManipulator(forms.Manipulator)
592         def __init__(self):
593             self.fields = (
594                 ...
595                 forms.IntegerField(field_name = "size", validator_list=[power_validator])
596             )
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
617     field has a value.
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.
651 ``NumberIsInRange``
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
654     given).
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).
660 ``IsAPowerOf``
661     Takes an integer argument and when called as a validator, checks that the
662     field being validated is a power of the integer.
664 ``IsValidDecimal``
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.
673 ``AnyValidator``
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
677     original list.
679 ``URLMimeTypeCheck``
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.
686 ``RelaxNGCompact``
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/