Saturday, December 08, 2007

Django Forms

Start with this basic Form subclass, which we’ll call ContactForm:

from django import newforms as forms

class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)

A form is composed of Field objects.

Creating Form instances

A Form instance is either bound to a set of data, or unbound.

* If it’s bound to a set of data, it’s capable of validating that data and rendering the form as HTML with the data displayed in the HTML.
* If it’s unbound, it cannot do validation but it can still render the blank form as HTML.

To create an unbound Form instance, simply instantiate the class:

>>> f = ContactForm()

To bind data to a form, pass the data as a dictionary as the first parameter to your Form class constructor:

>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> f = ContactForm(data)

In this dictionary, the keys are the field names, which correspond to the attributes in your Form class. The values are the data you’re trying to validate. These will usually be strings, but there’s no requirement that they be strings; the type of data you pass depends on the Field, as we’ll see in a moment.

If you need to distinguish between bound and unbound form instances at runtime, check the value of the form’s is_bound attribute:

>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({'subject': 'hello'})
>>> f.is_bound
True

Note that passing an empty dictionary creates a bound form with empty data:

>>> f = ContactForm({})
>>> f.is_bound
True

If you have a bound Form instance and want to change the data somehow, or if you want to bind an unbound Form instance to some data, create another Form instance. There is no way to change data in a Form instance. Once a Form instance has been created, you should consider its data immutable, whether it has data or not.


1) The primary task of a Form object is to validate data. With a bound Form instance, call the is_valid() method to run validation and return a boolean designating whether the data was valid:
2) Each Field in a Form class is responsible not only for validating data, but also for “cleaning” it — normalizing it to a consistent format.

f.errors
In this dictionary, the keys are the field names, and the values are lists of Unicode strings representing the error messages. The error messages are stored in lists because a field can have multiple error messages.

f.cleaned_data
If your data does not validate, your Form instance will not have a cleaned_data attribute:

cleaned_data will always only contain a key for fields defined in the Form, even if you pass extra data when you define the Form. In this example, we pass a bunch of extra fields to the ContactForm constructor, but cleaned_data contains only the form’s fields:

print f

You can access errors without having to call is_valid() first. The form’s data will be validated the first time either you call is_valid() or access errors.

The validation routines will only get called once, regardless of how many times you access errors or call is_valid()

Each field type has a default HTML representation. CharField and EmailField are represented by an . BooleanField is represented by an . Note these are merely sensible defaults; you can specify which HTML to use for a given field by using widgets

Use the auto_id argument to the Form constructor to control the label and id behavior. This argument must be True, False or a string.
If auto_id is False, then the form output will not include