~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to tests/regressiontests/forms/forms.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2009-07-29 11:26:28 UTC
  • mfrom: (1.1.8 upstream) (4.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20090729112628-pg09ino8sz0sj21t
Tags: 1.1-1
* New upstream release.
* Merge from experimental:
  - Ship FastCGI initscript and /etc/default file in python-django's examples
    directory (Closes: #538863)
  - Drop "05_10539-sphinx06-compatibility.diff"; it has been applied
    upstream.
  - Bump Standards-Version to 3.8.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
tests = r"""
 
3
>>> from django.forms import *
 
4
>>> from django.core.files.uploadedfile import SimpleUploadedFile
 
5
>>> import datetime
 
6
>>> import time
 
7
>>> import re
 
8
>>> try:
 
9
...     from decimal import Decimal
 
10
... except ImportError:
 
11
...     from django.utils._decimal import Decimal
 
12
 
 
13
#########
 
14
# Forms #
 
15
#########
 
16
 
 
17
A Form is a collection of Fields. It knows how to validate a set of data and it
 
18
knows how to render itself in a couple of default ways (e.g., an HTML table).
 
19
You can pass it data in __init__(), as a dictionary.
 
20
 
 
21
# Form ########################################################################
 
22
 
 
23
>>> class Person(Form):
 
24
...     first_name = CharField()
 
25
...     last_name = CharField()
 
26
...     birthday = DateField()
 
27
 
 
28
Pass a dictionary to a Form's __init__().
 
29
>>> p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'})
 
30
>>> p.is_bound
 
31
True
 
32
>>> p.errors
 
33
{}
 
34
>>> p.is_valid()
 
35
True
 
36
>>> p.errors.as_ul()
 
37
u''
 
38
>>> p.errors.as_text()
 
39
u''
 
40
>>> p.cleaned_data["first_name"], p.cleaned_data["last_name"], p.cleaned_data["birthday"]
 
41
(u'John', u'Lennon', datetime.date(1940, 10, 9))
 
42
>>> print p['first_name']
 
43
<input type="text" name="first_name" value="John" id="id_first_name" />
 
44
>>> print p['last_name']
 
45
<input type="text" name="last_name" value="Lennon" id="id_last_name" />
 
46
>>> print p['birthday']
 
47
<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
 
48
>>> print p['nonexistentfield']
 
49
Traceback (most recent call last):
 
50
...
 
51
KeyError: "Key 'nonexistentfield' not found in Form"
 
52
 
 
53
>>> for boundfield in p:
 
54
...     print boundfield
 
55
<input type="text" name="first_name" value="John" id="id_first_name" />
 
56
<input type="text" name="last_name" value="Lennon" id="id_last_name" />
 
57
<input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
 
58
>>> for boundfield in p:
 
59
...     print boundfield.label, boundfield.data
 
60
First name John
 
61
Last name Lennon
 
62
Birthday 1940-10-9
 
63
>>> print p
 
64
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
 
65
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" /></td></tr>
 
66
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>
 
67
 
 
68
Empty dictionaries are valid, too.
 
69
>>> p = Person({})
 
70
>>> p.is_bound
 
71
True
 
72
>>> p.errors['first_name']
 
73
[u'This field is required.']
 
74
>>> p.errors['last_name']
 
75
[u'This field is required.']
 
76
>>> p.errors['birthday']
 
77
[u'This field is required.']
 
78
>>> p.is_valid()
 
79
False
 
80
>>> p.cleaned_data
 
81
Traceback (most recent call last):
 
82
...
 
83
AttributeError: 'Person' object has no attribute 'cleaned_data'
 
84
>>> print p
 
85
<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
 
86
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
 
87
<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>
 
88
>>> print p.as_table()
 
89
<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
 
90
<tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
 
91
<tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>
 
92
>>> print p.as_ul()
 
93
<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
 
94
<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
 
95
<li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>
 
96
>>> print p.as_p()
 
97
<ul class="errorlist"><li>This field is required.</li></ul>
 
98
<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
 
99
<ul class="errorlist"><li>This field is required.</li></ul>
 
100
<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
 
101
<ul class="errorlist"><li>This field is required.</li></ul>
 
102
<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
 
103
 
 
104
If you don't pass any values to the Form's __init__(), or if you pass None,
 
105
the Form will be considered unbound and won't do any validation. Form.errors
 
106
will be an empty dictionary *but* Form.is_valid() will return False.
 
107
>>> p = Person()
 
108
>>> p.is_bound
 
109
False
 
110
>>> p.errors
 
111
{}
 
112
>>> p.is_valid()
 
113
False
 
114
>>> p.cleaned_data
 
115
Traceback (most recent call last):
 
116
...
 
117
AttributeError: 'Person' object has no attribute 'cleaned_data'
 
118
>>> print p
 
119
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
 
120
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
 
121
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
 
122
>>> print p.as_table()
 
123
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
 
124
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
 
125
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
 
126
>>> print p.as_ul()
 
127
<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
 
128
<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
 
129
<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>
 
130
>>> print p.as_p()
 
131
<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
 
132
<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
 
133
<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
 
134
 
 
135
Unicode values are handled properly.
 
136
>>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'})
 
137
>>> p.as_table()
 
138
u'<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>\n<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></td></tr>\n<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>'
 
139
>>> p.as_ul()
 
140
u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>'
 
141
>>> p.as_p()
 
142
u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>'
 
143
 
 
144
>>> p = Person({'last_name': u'Lennon'})
 
145
>>> p.errors['first_name']
 
146
[u'This field is required.']
 
147
>>> p.errors['birthday']
 
148
[u'This field is required.']
 
149
>>> p.is_valid()
 
150
False
 
151
>>> p.errors.as_ul()
 
152
u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>birthday<ul class="errorlist"><li>This field is required.</li></ul></li></ul>'
 
153
>>> print p.errors.as_text()
 
154
* first_name
 
155
  * This field is required.
 
156
* birthday
 
157
  * This field is required.
 
158
>>> p.cleaned_data
 
159
Traceback (most recent call last):
 
160
...
 
161
AttributeError: 'Person' object has no attribute 'cleaned_data'
 
162
>>> p['first_name'].errors
 
163
[u'This field is required.']
 
164
>>> p['first_name'].errors.as_ul()
 
165
u'<ul class="errorlist"><li>This field is required.</li></ul>'
 
166
>>> p['first_name'].errors.as_text()
 
167
u'* This field is required.'
 
168
 
 
169
>>> p = Person()
 
170
>>> print p['first_name']
 
171
<input type="text" name="first_name" id="id_first_name" />
 
172
>>> print p['last_name']
 
173
<input type="text" name="last_name" id="id_last_name" />
 
174
>>> print p['birthday']
 
175
<input type="text" name="birthday" id="id_birthday" />
 
176
 
 
177
cleaned_data will always *only* contain a key for fields defined in the
 
178
Form, even if you pass extra data when you define the Form. In this
 
179
example, we pass a bunch of extra fields to the form constructor,
 
180
but cleaned_data contains only the form's fields.
 
181
>>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'}
 
182
>>> p = Person(data)
 
183
>>> p.is_valid()
 
184
True
 
185
>>> p.cleaned_data['first_name']
 
186
u'John'
 
187
>>> p.cleaned_data['last_name']
 
188
u'Lennon'
 
189
>>> p.cleaned_data['birthday']
 
190
datetime.date(1940, 10, 9)
 
191
 
 
192
 
 
193
cleaned_data will include a key and value for *all* fields defined in the Form,
 
194
even if the Form's data didn't include a value for fields that are not
 
195
required. In this example, the data dictionary doesn't include a value for the
 
196
"nick_name" field, but cleaned_data includes it. For CharFields, it's set to the
 
197
empty string.
 
198
>>> class OptionalPersonForm(Form):
 
199
...     first_name = CharField()
 
200
...     last_name = CharField()
 
201
...     nick_name = CharField(required=False)
 
202
>>> data = {'first_name': u'John', 'last_name': u'Lennon'}
 
203
>>> f = OptionalPersonForm(data)
 
204
>>> f.is_valid()
 
205
True
 
206
>>> f.cleaned_data['nick_name']
 
207
u''
 
208
>>> f.cleaned_data['first_name']
 
209
u'John'
 
210
>>> f.cleaned_data['last_name']
 
211
u'Lennon'
 
212
 
 
213
For DateFields, it's set to None.
 
214
>>> class OptionalPersonForm(Form):
 
215
...     first_name = CharField()
 
216
...     last_name = CharField()
 
217
...     birth_date = DateField(required=False)
 
218
>>> data = {'first_name': u'John', 'last_name': u'Lennon'}
 
219
>>> f = OptionalPersonForm(data)
 
220
>>> f.is_valid()
 
221
True
 
222
>>> print f.cleaned_data['birth_date']
 
223
None
 
224
>>> f.cleaned_data['first_name']
 
225
u'John'
 
226
>>> f.cleaned_data['last_name']
 
227
u'Lennon'
 
228
 
 
229
"auto_id" tells the Form to add an "id" attribute to each form element.
 
230
If it's a string that contains '%s', Django will use that as a format string
 
231
into which the field's name will be inserted. It will also put a <label> around
 
232
the human-readable labels for a field.
 
233
>>> p = Person(auto_id='%s_id')
 
234
>>> print p.as_table()
 
235
<tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
 
236
<tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr>
 
237
<tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>
 
238
>>> print p.as_ul()
 
239
<li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
 
240
<li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li>
 
241
<li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>
 
242
>>> print p.as_p()
 
243
<p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
 
244
<p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p>
 
245
<p><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>
 
246
 
 
247
If auto_id is any True value whose str() does not contain '%s', the "id"
 
248
attribute will be the name of the field.
 
249
>>> p = Person(auto_id=True)
 
250
>>> print p.as_ul()
 
251
<li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
 
252
<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
 
253
<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
 
254
 
 
255
If auto_id is any False value, an "id" attribute won't be output unless it
 
256
was manually entered.
 
257
>>> p = Person(auto_id=False)
 
258
>>> print p.as_ul()
 
259
<li>First name: <input type="text" name="first_name" /></li>
 
260
<li>Last name: <input type="text" name="last_name" /></li>
 
261
<li>Birthday: <input type="text" name="birthday" /></li>
 
262
 
 
263
In this example, auto_id is False, but the "id" attribute for the "first_name"
 
264
field is given. Also note that field gets a <label>, while the others don't.
 
265
>>> class PersonNew(Form):
 
266
...     first_name = CharField(widget=TextInput(attrs={'id': 'first_name_id'}))
 
267
...     last_name = CharField()
 
268
...     birthday = DateField()
 
269
>>> p = PersonNew(auto_id=False)
 
270
>>> print p.as_ul()
 
271
<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
 
272
<li>Last name: <input type="text" name="last_name" /></li>
 
273
<li>Birthday: <input type="text" name="birthday" /></li>
 
274
 
 
275
If the "id" attribute is specified in the Form and auto_id is True, the "id"
 
276
attribute in the Form gets precedence.
 
277
>>> p = PersonNew(auto_id=True)
 
278
>>> print p.as_ul()
 
279
<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
 
280
<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
 
281
<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
 
282
 
 
283
>>> class SignupForm(Form):
 
284
...     email = EmailField()
 
285
...     get_spam = BooleanField()
 
286
>>> f = SignupForm(auto_id=False)
 
287
>>> print f['email']
 
288
<input type="text" name="email" />
 
289
>>> print f['get_spam']
 
290
<input type="checkbox" name="get_spam" />
 
291
 
 
292
>>> f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False)
 
293
>>> print f['email']
 
294
<input type="text" name="email" value="test@example.com" />
 
295
>>> print f['get_spam']
 
296
<input checked="checked" type="checkbox" name="get_spam" />
 
297
 
 
298
Any Field can have a Widget class passed to its constructor:
 
299
>>> class ContactForm(Form):
 
300
...     subject = CharField()
 
301
...     message = CharField(widget=Textarea)
 
302
>>> f = ContactForm(auto_id=False)
 
303
>>> print f['subject']
 
304
<input type="text" name="subject" />
 
305
>>> print f['message']
 
306
<textarea rows="10" cols="40" name="message"></textarea>
 
307
 
 
308
as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
 
309
widget type:
 
310
>>> f['subject'].as_textarea()
 
311
u'<textarea rows="10" cols="40" name="subject"></textarea>'
 
312
>>> f['message'].as_text()
 
313
u'<input type="text" name="message" />'
 
314
>>> f['message'].as_hidden()
 
315
u'<input type="hidden" name="message" />'
 
316
 
 
317
The 'widget' parameter to a Field can also be an instance:
 
318
>>> class ContactForm(Form):
 
319
...     subject = CharField()
 
320
...     message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20}))
 
321
>>> f = ContactForm(auto_id=False)
 
322
>>> print f['message']
 
323
<textarea rows="80" cols="20" name="message"></textarea>
 
324
 
 
325
Instance-level attrs are *not* carried over to as_textarea(), as_text() and
 
326
as_hidden():
 
327
>>> f['message'].as_text()
 
328
u'<input type="text" name="message" />'
 
329
>>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False)
 
330
>>> f['subject'].as_textarea()
 
331
u'<textarea rows="10" cols="40" name="subject">Hello</textarea>'
 
332
>>> f['message'].as_text()
 
333
u'<input type="text" name="message" value="I love you." />'
 
334
>>> f['message'].as_hidden()
 
335
u'<input type="hidden" name="message" value="I love you." />'
 
336
 
 
337
For a form with a <select>, use ChoiceField:
 
338
>>> class FrameworkForm(Form):
 
339
...     name = CharField()
 
340
...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')])
 
341
>>> f = FrameworkForm(auto_id=False)
 
342
>>> print f['language']
 
343
<select name="language">
 
344
<option value="P">Python</option>
 
345
<option value="J">Java</option>
 
346
</select>
 
347
>>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
 
348
>>> print f['language']
 
349
<select name="language">
 
350
<option value="P" selected="selected">Python</option>
 
351
<option value="J">Java</option>
 
352
</select>
 
353
 
 
354
A subtlety: If one of the choices' value is the empty string and the form is
 
355
unbound, then the <option> for the empty-string choice will get selected="selected".
 
356
>>> class FrameworkForm(Form):
 
357
...     name = CharField()
 
358
...     language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')])
 
359
>>> f = FrameworkForm(auto_id=False)
 
360
>>> print f['language']
 
361
<select name="language">
 
362
<option value="" selected="selected">------</option>
 
363
<option value="P">Python</option>
 
364
<option value="J">Java</option>
 
365
</select>
 
366
 
 
367
You can specify widget attributes in the Widget constructor.
 
368
>>> class FrameworkForm(Form):
 
369
...     name = CharField()
 
370
...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(attrs={'class': 'foo'}))
 
371
>>> f = FrameworkForm(auto_id=False)
 
372
>>> print f['language']
 
373
<select class="foo" name="language">
 
374
<option value="P">Python</option>
 
375
<option value="J">Java</option>
 
376
</select>
 
377
>>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
 
378
>>> print f['language']
 
379
<select class="foo" name="language">
 
380
<option value="P" selected="selected">Python</option>
 
381
<option value="J">Java</option>
 
382
</select>
 
383
 
 
384
When passing a custom widget instance to ChoiceField, note that setting
 
385
'choices' on the widget is meaningless. The widget will use the choices
 
386
defined on the Field, not the ones defined on the Widget.
 
387
>>> class FrameworkForm(Form):
 
388
...     name = CharField()
 
389
...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(choices=[('R', 'Ruby'), ('P', 'Perl')], attrs={'class': 'foo'}))
 
390
>>> f = FrameworkForm(auto_id=False)
 
391
>>> print f['language']
 
392
<select class="foo" name="language">
 
393
<option value="P">Python</option>
 
394
<option value="J">Java</option>
 
395
</select>
 
396
>>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
 
397
>>> print f['language']
 
398
<select class="foo" name="language">
 
399
<option value="P" selected="selected">Python</option>
 
400
<option value="J">Java</option>
 
401
</select>
 
402
 
 
403
You can set a ChoiceField's choices after the fact.
 
404
>>> class FrameworkForm(Form):
 
405
...     name = CharField()
 
406
...     language = ChoiceField()
 
407
>>> f = FrameworkForm(auto_id=False)
 
408
>>> print f['language']
 
409
<select name="language">
 
410
</select>
 
411
>>> f.fields['language'].choices = [('P', 'Python'), ('J', 'Java')]
 
412
>>> print f['language']
 
413
<select name="language">
 
414
<option value="P">Python</option>
 
415
<option value="J">Java</option>
 
416
</select>
 
417
 
 
418
Add widget=RadioSelect to use that widget with a ChoiceField.
 
419
>>> class FrameworkForm(Form):
 
420
...     name = CharField()
 
421
...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=RadioSelect)
 
422
>>> f = FrameworkForm(auto_id=False)
 
423
>>> print f['language']
 
424
<ul>
 
425
<li><label><input type="radio" name="language" value="P" /> Python</label></li>
 
426
<li><label><input type="radio" name="language" value="J" /> Java</label></li>
 
427
</ul>
 
428
>>> print f
 
429
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
 
430
<tr><th>Language:</th><td><ul>
 
431
<li><label><input type="radio" name="language" value="P" /> Python</label></li>
 
432
<li><label><input type="radio" name="language" value="J" /> Java</label></li>
 
433
</ul></td></tr>
 
434
>>> print f.as_ul()
 
435
<li>Name: <input type="text" name="name" /></li>
 
436
<li>Language: <ul>
 
437
<li><label><input type="radio" name="language" value="P" /> Python</label></li>
 
438
<li><label><input type="radio" name="language" value="J" /> Java</label></li>
 
439
</ul></li>
 
440
 
 
441
Regarding auto_id and <label>, RadioSelect is a special case. Each radio button
 
442
gets a distinct ID, formed by appending an underscore plus the button's
 
443
zero-based index.
 
444
>>> f = FrameworkForm(auto_id='id_%s')
 
445
>>> print f['language']
 
446
<ul>
 
447
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
 
448
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 
449
</ul>
 
450
 
 
451
When RadioSelect is used with auto_id, and the whole form is printed using
 
452
either as_table() or as_ul(), the label for the RadioSelect will point to the
 
453
ID of the *first* radio button.
 
454
>>> print f
 
455
<tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" /></td></tr>
 
456
<tr><th><label for="id_language_0">Language:</label></th><td><ul>
 
457
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
 
458
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 
459
</ul></td></tr>
 
460
>>> print f.as_ul()
 
461
<li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li>
 
462
<li><label for="id_language_0">Language:</label> <ul>
 
463
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
 
464
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 
465
</ul></li>
 
466
>>> print f.as_p()
 
467
<p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p>
 
468
<p><label for="id_language_0">Language:</label> <ul>
 
469
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
 
470
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 
471
</ul></p>
 
472
 
 
473
MultipleChoiceField is a special case, as its data is required to be a list:
 
474
>>> class SongForm(Form):
 
475
...     name = CharField()
 
476
...     composers = MultipleChoiceField()
 
477
>>> f = SongForm(auto_id=False)
 
478
>>> print f['composers']
 
479
<select multiple="multiple" name="composers">
 
480
</select>
 
481
>>> class SongForm(Form):
 
482
...     name = CharField()
 
483
...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')])
 
484
>>> f = SongForm(auto_id=False)
 
485
>>> print f['composers']
 
486
<select multiple="multiple" name="composers">
 
487
<option value="J">John Lennon</option>
 
488
<option value="P">Paul McCartney</option>
 
489
</select>
 
490
>>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
 
491
>>> print f['name']
 
492
<input type="text" name="name" value="Yesterday" />
 
493
>>> print f['composers']
 
494
<select multiple="multiple" name="composers">
 
495
<option value="J">John Lennon</option>
 
496
<option value="P" selected="selected">Paul McCartney</option>
 
497
</select>
 
498
 
 
499
MultipleChoiceField rendered as_hidden() is a special case. Because it can
 
500
have multiple values, its as_hidden() renders multiple <input type="hidden">
 
501
tags.
 
502
>>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
 
503
>>> print f['composers'].as_hidden()
 
504
<input type="hidden" name="composers" value="P" />
 
505
>>> f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False)
 
506
>>> print f['composers'].as_hidden()
 
507
<input type="hidden" name="composers" value="P" />
 
508
<input type="hidden" name="composers" value="J" />
 
509
 
 
510
MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
 
511
>>> class SongForm(Form):
 
512
...     name = CharField()
 
513
...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple)
 
514
>>> f = SongForm(auto_id=False)
 
515
>>> print f['composers']
 
516
<ul>
 
517
<li><label><input type="checkbox" name="composers" value="J" /> John Lennon</label></li>
 
518
<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
 
519
</ul>
 
520
>>> f = SongForm({'composers': ['J']}, auto_id=False)
 
521
>>> print f['composers']
 
522
<ul>
 
523
<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
 
524
<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
 
525
</ul>
 
526
>>> f = SongForm({'composers': ['J', 'P']}, auto_id=False)
 
527
>>> print f['composers']
 
528
<ul>
 
529
<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
 
530
<li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
 
531
</ul>
 
532
 
 
533
Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox
 
534
gets a distinct ID, formed by appending an underscore plus the checkbox's
 
535
zero-based index.
 
536
>>> f = SongForm(auto_id='%s_id')
 
537
>>> print f['composers']
 
538
<ul>
 
539
<li><label for="composers_id_0"><input type="checkbox" name="composers" value="J" id="composers_id_0" /> John Lennon</label></li>
 
540
<li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li>
 
541
</ul>
 
542
 
 
543
Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and
 
544
MergeDict (when created as a merge of MultiValueDicts) conveniently work with
 
545
this.
 
546
>>> data = {'name': 'Yesterday', 'composers': ['J', 'P']}
 
547
>>> f = SongForm(data)
 
548
>>> f.errors
 
549
{}
 
550
>>> from django.http import QueryDict
 
551
>>> data = QueryDict('name=Yesterday&composers=J&composers=P')
 
552
>>> f = SongForm(data)
 
553
>>> f.errors
 
554
{}
 
555
>>> from django.utils.datastructures import MultiValueDict
 
556
>>> data = MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))
 
557
>>> f = SongForm(data)
 
558
>>> f.errors
 
559
{}
 
560
>>> from django.utils.datastructures import MergeDict
 
561
>>> data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])))
 
562
>>> f = SongForm(data)
 
563
>>> f.errors
 
564
{}
 
565
 
 
566
The MultipleHiddenInput widget renders multiple values as hidden fields.
 
567
>>> class SongFormHidden(Form):
 
568
...     name = CharField()
 
569
...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=MultipleHiddenInput)
 
570
>>> f = SongFormHidden(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])), auto_id=False)
 
571
>>> print f.as_ul()
 
572
<li>Name: <input type="text" name="name" value="Yesterday" /><input type="hidden" name="composers" value="J" />
 
573
<input type="hidden" name="composers" value="P" /></li>
 
574
 
 
575
When using CheckboxSelectMultiple, the framework expects a list of input and
 
576
returns a list of input.
 
577
>>> f = SongForm({'name': 'Yesterday'}, auto_id=False)
 
578
>>> f.errors['composers']
 
579
[u'This field is required.']
 
580
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
 
581
>>> f.errors
 
582
{}
 
583
>>> f.cleaned_data['composers']
 
584
[u'J']
 
585
>>> f.cleaned_data['name']
 
586
u'Yesterday'
 
587
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
 
588
>>> f.errors
 
589
{}
 
590
>>> f.cleaned_data['composers']
 
591
[u'J', u'P']
 
592
>>> f.cleaned_data['name']
 
593
u'Yesterday'
 
594
 
 
595
Validation errors are HTML-escaped when output as HTML.
 
596
>>> from django.utils.safestring import mark_safe
 
597
>>> class EscapingForm(Form):
 
598
...     special_name = CharField(label="<em>Special</em> Field")
 
599
...     special_safe_name = CharField(label=mark_safe("<em>Special</em> Field"))
 
600
...     def clean_special_name(self):
 
601
...         raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name'])
 
602
...     def clean_special_safe_name(self):
 
603
...         raise ValidationError(mark_safe("'<b>%s</b>' is a safe string" % self.cleaned_data['special_safe_name']))
 
604
 
 
605
>>> f = EscapingForm({'special_name': "Nothing to escape", 'special_safe_name': "Nothing to escape"}, auto_id=False)
 
606
>>> print f
 
607
<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Nothing to escape&#39;</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr>
 
608
<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b>Nothing to escape</b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="Nothing to escape" /></td></tr>
 
609
>>> f = EscapingForm(
 
610
...     {'special_name': "Should escape < & > and <script>alert('xss')</script>",
 
611
...     'special_safe_name': "<i>Do not escape</i>"}, auto_id=False)
 
612
>>> print f
 
613
<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;&#39;</li></ul><input type="text" name="special_name" value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;" /></td></tr>
 
614
<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b><i>Do not escape</i></b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="&lt;i&gt;Do not escape&lt;/i&gt;" /></td></tr>
 
615
 
 
616
""" + \
 
617
r""" # [This concatenation is to keep the string below the jython's 32K limit].
 
618
# Validating multiple fields in relation to another ###########################
 
619
 
 
620
There are a couple of ways to do multiple-field validation. If you want the
 
621
validation message to be associated with a particular field, implement the
 
622
clean_XXX() method on the Form, where XXX is the field name. As in
 
623
Field.clean(), the clean_XXX() method should return the cleaned value. In the
 
624
clean_XXX() method, you have access to self.cleaned_data, which is a dictionary
 
625
of all the data that has been cleaned *so far*, in order by the fields,
 
626
including the current field (e.g., the field XXX if you're in clean_XXX()).
 
627
>>> class UserRegistration(Form):
 
628
...    username = CharField(max_length=10)
 
629
...    password1 = CharField(widget=PasswordInput)
 
630
...    password2 = CharField(widget=PasswordInput)
 
631
...    def clean_password2(self):
 
632
...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
 
633
...            raise ValidationError(u'Please make sure your passwords match.')
 
634
...        return self.cleaned_data['password2']
 
635
>>> f = UserRegistration(auto_id=False)
 
636
>>> f.errors
 
637
{}
 
638
>>> f = UserRegistration({}, auto_id=False)
 
639
>>> f.errors['username']
 
640
[u'This field is required.']
 
641
>>> f.errors['password1']
 
642
[u'This field is required.']
 
643
>>> f.errors['password2']
 
644
[u'This field is required.']
 
645
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
 
646
>>> f.errors['password2']
 
647
[u'Please make sure your passwords match.']
 
648
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
 
649
>>> f.errors
 
650
{}
 
651
>>> f.cleaned_data['username']
 
652
u'adrian'
 
653
>>> f.cleaned_data['password1']
 
654
u'foo'
 
655
>>> f.cleaned_data['password2']
 
656
u'foo'
 
657
 
 
658
Another way of doing multiple-field validation is by implementing the
 
659
Form's clean() method. If you do this, any ValidationError raised by that
 
660
method will not be associated with a particular field; it will have a
 
661
special-case association with the field named '__all__'.
 
662
Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of
 
663
all the fields/values that have *not* raised a ValidationError. Also note
 
664
Form.clean() is required to return a dictionary of all clean data.
 
665
>>> class UserRegistration(Form):
 
666
...    username = CharField(max_length=10)
 
667
...    password1 = CharField(widget=PasswordInput)
 
668
...    password2 = CharField(widget=PasswordInput)
 
669
...    def clean(self):
 
670
...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
 
671
...            raise ValidationError(u'Please make sure your passwords match.')
 
672
...        return self.cleaned_data
 
673
>>> f = UserRegistration(auto_id=False)
 
674
>>> f.errors
 
675
{}
 
676
>>> f = UserRegistration({}, auto_id=False)
 
677
>>> print f.as_table()
 
678
<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
 
679
<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
 
680
<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
 
681
>>> f.errors['username']
 
682
[u'This field is required.']
 
683
>>> f.errors['password1']
 
684
[u'This field is required.']
 
685
>>> f.errors['password2']
 
686
[u'This field is required.']
 
687
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
 
688
>>> f.errors['__all__']
 
689
[u'Please make sure your passwords match.']
 
690
>>> print f.as_table()
 
691
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
 
692
<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
 
693
<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
 
694
<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
 
695
>>> print f.as_ul()
 
696
<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li>
 
697
<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
 
698
<li>Password1: <input type="password" name="password1" value="foo" /></li>
 
699
<li>Password2: <input type="password" name="password2" value="bar" /></li>
 
700
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
 
701
>>> f.errors
 
702
{}
 
703
>>> f.cleaned_data['username']
 
704
u'adrian'
 
705
>>> f.cleaned_data['password1']
 
706
u'foo'
 
707
>>> f.cleaned_data['password2']
 
708
u'foo'
 
709
 
 
710
# Dynamic construction ########################################################
 
711
 
 
712
It's possible to construct a Form dynamically by adding to the self.fields
 
713
dictionary in __init__(). Don't forget to call Form.__init__() within the
 
714
subclass' __init__().
 
715
>>> class Person(Form):
 
716
...     first_name = CharField()
 
717
...     last_name = CharField()
 
718
...     def __init__(self, *args, **kwargs):
 
719
...         super(Person, self).__init__(*args, **kwargs)
 
720
...         self.fields['birthday'] = DateField()
 
721
>>> p = Person(auto_id=False)
 
722
>>> print p
 
723
<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
 
724
<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
 
725
<tr><th>Birthday:</th><td><input type="text" name="birthday" /></td></tr>
 
726
 
 
727
Instances of a dynamic Form do not persist fields from one Form instance to
 
728
the next.
 
729
>>> class MyForm(Form):
 
730
...     def __init__(self, data=None, auto_id=False, field_list=[]):
 
731
...         Form.__init__(self, data, auto_id=auto_id)
 
732
...         for field in field_list:
 
733
...             self.fields[field[0]] = field[1]
 
734
>>> field_list = [('field1', CharField()), ('field2', CharField())]
 
735
>>> my_form = MyForm(field_list=field_list)
 
736
>>> print my_form
 
737
<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
 
738
<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
 
739
>>> field_list = [('field3', CharField()), ('field4', CharField())]
 
740
>>> my_form = MyForm(field_list=field_list)
 
741
>>> print my_form
 
742
<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
 
743
<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
 
744
 
 
745
>>> class MyForm(Form):
 
746
...     default_field_1 = CharField()
 
747
...     default_field_2 = CharField()
 
748
...     def __init__(self, data=None, auto_id=False, field_list=[]):
 
749
...         Form.__init__(self, data, auto_id=auto_id)
 
750
...         for field in field_list:
 
751
...             self.fields[field[0]] = field[1]
 
752
>>> field_list = [('field1', CharField()), ('field2', CharField())]
 
753
>>> my_form = MyForm(field_list=field_list)
 
754
>>> print my_form
 
755
<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
 
756
<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
 
757
<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
 
758
<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
 
759
>>> field_list = [('field3', CharField()), ('field4', CharField())]
 
760
>>> my_form = MyForm(field_list=field_list)
 
761
>>> print my_form
 
762
<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
 
763
<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
 
764
<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
 
765
<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
 
766
 
 
767
Similarly, changes to field attributes do not persist from one Form instance
 
768
to the next.
 
769
>>> class Person(Form):
 
770
...     first_name = CharField(required=False)
 
771
...     last_name = CharField(required=False)
 
772
...     def __init__(self, names_required=False, *args, **kwargs):
 
773
...         super(Person, self).__init__(*args, **kwargs)
 
774
...         if names_required:
 
775
...             self.fields['first_name'].required = True
 
776
...             self.fields['first_name'].widget.attrs['class'] = 'required'
 
777
...             self.fields['last_name'].required = True
 
778
...             self.fields['last_name'].widget.attrs['class'] = 'required'
 
779
>>> f = Person(names_required=False)
 
780
>>> f['first_name'].field.required, f['last_name'].field.required
 
781
(False, False)
 
782
>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
 
783
({}, {})
 
784
>>> f = Person(names_required=True)
 
785
>>> f['first_name'].field.required, f['last_name'].field.required
 
786
(True, True)
 
787
>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
 
788
({'class': 'required'}, {'class': 'required'})
 
789
>>> f = Person(names_required=False)
 
790
>>> f['first_name'].field.required, f['last_name'].field.required
 
791
(False, False)
 
792
>>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
 
793
({}, {})
 
794
>>> class Person(Form):
 
795
...     first_name = CharField(max_length=30)
 
796
...     last_name = CharField(max_length=30)
 
797
...     def __init__(self, name_max_length=None, *args, **kwargs):
 
798
...         super(Person, self).__init__(*args, **kwargs)
 
799
...         if name_max_length:
 
800
...             self.fields['first_name'].max_length = name_max_length
 
801
...             self.fields['last_name'].max_length = name_max_length
 
802
>>> f = Person(name_max_length=None)
 
803
>>> f['first_name'].field.max_length, f['last_name'].field.max_length
 
804
(30, 30)
 
805
>>> f = Person(name_max_length=20)
 
806
>>> f['first_name'].field.max_length, f['last_name'].field.max_length
 
807
(20, 20)
 
808
>>> f = Person(name_max_length=None)
 
809
>>> f['first_name'].field.max_length, f['last_name'].field.max_length
 
810
(30, 30)
 
811
 
 
812
HiddenInput widgets are displayed differently in the as_table(), as_ul()
 
813
and as_p() output of a Form -- their verbose names are not displayed, and a
 
814
separate row is not displayed. They're displayed in the last row of the
 
815
form, directly after that row's form element.
 
816
>>> class Person(Form):
 
817
...     first_name = CharField()
 
818
...     last_name = CharField()
 
819
...     hidden_text = CharField(widget=HiddenInput)
 
820
...     birthday = DateField()
 
821
>>> p = Person(auto_id=False)
 
822
>>> print p
 
823
<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
 
824
<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
 
825
<tr><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr>
 
826
>>> print p.as_ul()
 
827
<li>First name: <input type="text" name="first_name" /></li>
 
828
<li>Last name: <input type="text" name="last_name" /></li>
 
829
<li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li>
 
830
>>> print p.as_p()
 
831
<p>First name: <input type="text" name="first_name" /></p>
 
832
<p>Last name: <input type="text" name="last_name" /></p>
 
833
<p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p>
 
834
 
 
835
With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label.
 
836
>>> p = Person(auto_id='id_%s')
 
837
>>> print p
 
838
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
 
839
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
 
840
<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></td></tr>
 
841
>>> print p.as_ul()
 
842
<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
 
843
<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
 
844
<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></li>
 
845
>>> print p.as_p()
 
846
<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
 
847
<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
 
848
<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></p>
 
849
 
 
850
If a field with a HiddenInput has errors, the as_table() and as_ul() output
 
851
will include the error message(s) with the text "(Hidden field [fieldname]) "
 
852
prepended. This message is displayed at the top of the output, regardless of
 
853
its field's order in the form.
 
854
>>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
 
855
>>> print p
 
856
<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr>
 
857
<tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
 
858
<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
 
859
<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>
 
860
>>> print p.as_ul()
 
861
<li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li>
 
862
<li>First name: <input type="text" name="first_name" value="John" /></li>
 
863
<li>Last name: <input type="text" name="last_name" value="Lennon" /></li>
 
864
<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li>
 
865
>>> print p.as_p()
 
866
<ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul>
 
867
<p>First name: <input type="text" name="first_name" value="John" /></p>
 
868
<p>Last name: <input type="text" name="last_name" value="Lennon" /></p>
 
869
<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p>
 
870
 
 
871
A corner case: It's possible for a form to have only HiddenInputs.
 
872
>>> class TestForm(Form):
 
873
...     foo = CharField(widget=HiddenInput)
 
874
...     bar = CharField(widget=HiddenInput)
 
875
>>> p = TestForm(auto_id=False)
 
876
>>> print p.as_table()
 
877
<input type="hidden" name="foo" /><input type="hidden" name="bar" />
 
878
>>> print p.as_ul()
 
879
<input type="hidden" name="foo" /><input type="hidden" name="bar" />
 
880
>>> print p.as_p()
 
881
<input type="hidden" name="foo" /><input type="hidden" name="bar" />
 
882
 
 
883
A Form's fields are displayed in the same order in which they were defined.
 
884
>>> class TestForm(Form):
 
885
...     field1 = CharField()
 
886
...     field2 = CharField()
 
887
...     field3 = CharField()
 
888
...     field4 = CharField()
 
889
...     field5 = CharField()
 
890
...     field6 = CharField()
 
891
...     field7 = CharField()
 
892
...     field8 = CharField()
 
893
...     field9 = CharField()
 
894
...     field10 = CharField()
 
895
...     field11 = CharField()
 
896
...     field12 = CharField()
 
897
...     field13 = CharField()
 
898
...     field14 = CharField()
 
899
>>> p = TestForm(auto_id=False)
 
900
>>> print p
 
901
<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
 
902
<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
 
903
<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
 
904
<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
 
905
<tr><th>Field5:</th><td><input type="text" name="field5" /></td></tr>
 
906
<tr><th>Field6:</th><td><input type="text" name="field6" /></td></tr>
 
907
<tr><th>Field7:</th><td><input type="text" name="field7" /></td></tr>
 
908
<tr><th>Field8:</th><td><input type="text" name="field8" /></td></tr>
 
909
<tr><th>Field9:</th><td><input type="text" name="field9" /></td></tr>
 
910
<tr><th>Field10:</th><td><input type="text" name="field10" /></td></tr>
 
911
<tr><th>Field11:</th><td><input type="text" name="field11" /></td></tr>
 
912
<tr><th>Field12:</th><td><input type="text" name="field12" /></td></tr>
 
913
<tr><th>Field13:</th><td><input type="text" name="field13" /></td></tr>
 
914
<tr><th>Field14:</th><td><input type="text" name="field14" /></td></tr>
 
915
 
 
916
Some Field classes have an effect on the HTML attributes of their associated
 
917
Widget. If you set max_length in a CharField and its associated widget is
 
918
either a TextInput or PasswordInput, then the widget's rendered HTML will
 
919
include the "maxlength" attribute.
 
920
>>> class UserRegistration(Form):
 
921
...    username = CharField(max_length=10)                   # uses TextInput by default
 
922
...    password = CharField(max_length=10, widget=PasswordInput)
 
923
...    realname = CharField(max_length=10, widget=TextInput) # redundantly define widget, just to test
 
924
...    address = CharField()                                 # no max_length defined here
 
925
>>> p = UserRegistration(auto_id=False)
 
926
>>> print p.as_ul()
 
927
<li>Username: <input type="text" name="username" maxlength="10" /></li>
 
928
<li>Password: <input type="password" name="password" maxlength="10" /></li>
 
929
<li>Realname: <input type="text" name="realname" maxlength="10" /></li>
 
930
<li>Address: <input type="text" name="address" /></li>
 
931
 
 
932
If you specify a custom "attrs" that includes the "maxlength" attribute,
 
933
the Field's max_length attribute will override whatever "maxlength" you specify
 
934
in "attrs".
 
935
>>> class UserRegistration(Form):
 
936
...    username = CharField(max_length=10, widget=TextInput(attrs={'maxlength': 20}))
 
937
...    password = CharField(max_length=10, widget=PasswordInput)
 
938
>>> p = UserRegistration(auto_id=False)
 
939
>>> print p.as_ul()
 
940
<li>Username: <input type="text" name="username" maxlength="10" /></li>
 
941
<li>Password: <input type="password" name="password" maxlength="10" /></li>
 
942
 
 
943
# Specifying labels ###########################################################
 
944
 
 
945
You can specify the label for a field by using the 'label' argument to a Field
 
946
class. If you don't specify 'label', Django will use the field name with
 
947
underscores converted to spaces, and the initial letter capitalized.
 
948
>>> class UserRegistration(Form):
 
949
...    username = CharField(max_length=10, label='Your username')
 
950
...    password1 = CharField(widget=PasswordInput)
 
951
...    password2 = CharField(widget=PasswordInput, label='Password (again)')
 
952
>>> p = UserRegistration(auto_id=False)
 
953
>>> print p.as_ul()
 
954
<li>Your username: <input type="text" name="username" maxlength="10" /></li>
 
955
<li>Password1: <input type="password" name="password1" /></li>
 
956
<li>Password (again): <input type="password" name="password2" /></li>
 
957
 
 
958
Labels for as_* methods will only end in a colon if they don't end in other
 
959
punctuation already.
 
960
>>> class Questions(Form):
 
961
...    q1 = CharField(label='The first question')
 
962
...    q2 = CharField(label='What is your name?')
 
963
...    q3 = CharField(label='The answer to life is:')
 
964
...    q4 = CharField(label='Answer this question!')
 
965
...    q5 = CharField(label='The last question. Period.')
 
966
>>> print Questions(auto_id=False).as_p()
 
967
<p>The first question: <input type="text" name="q1" /></p>
 
968
<p>What is your name? <input type="text" name="q2" /></p>
 
969
<p>The answer to life is: <input type="text" name="q3" /></p>
 
970
<p>Answer this question! <input type="text" name="q4" /></p>
 
971
<p>The last question. Period. <input type="text" name="q5" /></p>
 
972
>>> print Questions().as_p()
 
973
<p><label for="id_q1">The first question:</label> <input type="text" name="q1" id="id_q1" /></p>
 
974
<p><label for="id_q2">What is your name?</label> <input type="text" name="q2" id="id_q2" /></p>
 
975
<p><label for="id_q3">The answer to life is:</label> <input type="text" name="q3" id="id_q3" /></p>
 
976
<p><label for="id_q4">Answer this question!</label> <input type="text" name="q4" id="id_q4" /></p>
 
977
<p><label for="id_q5">The last question. Period.</label> <input type="text" name="q5" id="id_q5" /></p>
 
978
 
 
979
A label can be a Unicode object or a bytestring with special characters.
 
980
>>> class UserRegistration(Form):
 
981
...    username = CharField(max_length=10, label='ŠĐĆŽćžšđ')
 
982
...    password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 
983
>>> p = UserRegistration(auto_id=False)
 
984
>>> p.as_ul()
 
985
u'<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="text" name="username" maxlength="10" /></li>\n<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="password" name="password" /></li>'
 
986
 
 
987
If a label is set to the empty string for a field, that field won't get a label.
 
988
>>> class UserRegistration(Form):
 
989
...    username = CharField(max_length=10, label='')
 
990
...    password = CharField(widget=PasswordInput)
 
991
>>> p = UserRegistration(auto_id=False)
 
992
>>> print p.as_ul()
 
993
<li> <input type="text" name="username" maxlength="10" /></li>
 
994
<li>Password: <input type="password" name="password" /></li>
 
995
>>> p = UserRegistration(auto_id='id_%s')
 
996
>>> print p.as_ul()
 
997
<li> <input id="id_username" type="text" name="username" maxlength="10" /></li>
 
998
<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
 
999
 
 
1000
If label is None, Django will auto-create the label from the field name. This
 
1001
is default behavior.
 
1002
>>> class UserRegistration(Form):
 
1003
...    username = CharField(max_length=10, label=None)
 
1004
...    password = CharField(widget=PasswordInput)
 
1005
>>> p = UserRegistration(auto_id=False)
 
1006
>>> print p.as_ul()
 
1007
<li>Username: <input type="text" name="username" maxlength="10" /></li>
 
1008
<li>Password: <input type="password" name="password" /></li>
 
1009
>>> p = UserRegistration(auto_id='id_%s')
 
1010
>>> print p.as_ul()
 
1011
<li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></li>
 
1012
<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
 
1013
 
 
1014
 
 
1015
# Label Suffix ################################################################
 
1016
 
 
1017
You can specify the 'label_suffix' argument to a Form class to modify the
 
1018
punctuation symbol used at the end of a label.  By default, the colon (:) is
 
1019
used, and is only appended to the label if the label doesn't already end with a
 
1020
punctuation symbol: ., !, ? or :.  If you specify a different suffix, it will
 
1021
be appended regardless of the last character of the label.
 
1022
 
 
1023
>>> class FavoriteForm(Form):
 
1024
...     color = CharField(label='Favorite color?')
 
1025
...     animal = CharField(label='Favorite animal')
 
1026
...
 
1027
>>> f = FavoriteForm(auto_id=False)
 
1028
>>> print f.as_ul()
 
1029
<li>Favorite color? <input type="text" name="color" /></li>
 
1030
<li>Favorite animal: <input type="text" name="animal" /></li>
 
1031
>>> f = FavoriteForm(auto_id=False, label_suffix='?')
 
1032
>>> print f.as_ul()
 
1033
<li>Favorite color? <input type="text" name="color" /></li>
 
1034
<li>Favorite animal? <input type="text" name="animal" /></li>
 
1035
>>> f = FavoriteForm(auto_id=False, label_suffix='')
 
1036
>>> print f.as_ul()
 
1037
<li>Favorite color? <input type="text" name="color" /></li>
 
1038
<li>Favorite animal <input type="text" name="animal" /></li>
 
1039
>>> f = FavoriteForm(auto_id=False, label_suffix=u'\u2192')
 
1040
>>> f.as_ul()
 
1041
u'<li>Favorite color? <input type="text" name="color" /></li>\n<li>Favorite animal\u2192 <input type="text" name="animal" /></li>'
 
1042
 
 
1043
""" + \
 
1044
r""" # [This concatenation is to keep the string below the jython's 32K limit].
 
1045
 
 
1046
# Initial data ################################################################
 
1047
 
 
1048
You can specify initial data for a field by using the 'initial' argument to a
 
1049
Field class. This initial data is displayed when a Form is rendered with *no*
 
1050
data. It is not displayed when a Form is rendered with any data (including an
 
1051
empty dictionary). Also, the initial value is *not* used if data for a
 
1052
particular required field isn't provided.
 
1053
>>> class UserRegistration(Form):
 
1054
...    username = CharField(max_length=10, initial='django')
 
1055
...    password = CharField(widget=PasswordInput)
 
1056
 
 
1057
Here, we're not submitting any data, so the initial value will be displayed.
 
1058
>>> p = UserRegistration(auto_id=False)
 
1059
>>> print p.as_ul()
 
1060
<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
 
1061
<li>Password: <input type="password" name="password" /></li>
 
1062
 
 
1063
Here, we're submitting data, so the initial value will *not* be displayed.
 
1064
>>> p = UserRegistration({}, auto_id=False)
 
1065
>>> print p.as_ul()
 
1066
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1067
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1068
>>> p = UserRegistration({'username': u''}, auto_id=False)
 
1069
>>> print p.as_ul()
 
1070
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1071
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1072
>>> p = UserRegistration({'username': u'foo'}, auto_id=False)
 
1073
>>> print p.as_ul()
 
1074
<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
 
1075
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1076
 
 
1077
An 'initial' value is *not* used as a fallback if data is not provided. In this
 
1078
example, we don't provide a value for 'username', and the form raises a
 
1079
validation error rather than using the initial value for 'username'.
 
1080
>>> p = UserRegistration({'password': 'secret'})
 
1081
>>> p.errors['username']
 
1082
[u'This field is required.']
 
1083
>>> p.is_valid()
 
1084
False
 
1085
 
 
1086
# Dynamic initial data ########################################################
 
1087
 
 
1088
The previous technique dealt with "hard-coded" initial data, but it's also
 
1089
possible to specify initial data after you've already created the Form class
 
1090
(i.e., at runtime). Use the 'initial' parameter to the Form constructor. This
 
1091
should be a dictionary containing initial values for one or more fields in the
 
1092
form, keyed by field name.
 
1093
 
 
1094
>>> class UserRegistration(Form):
 
1095
...    username = CharField(max_length=10)
 
1096
...    password = CharField(widget=PasswordInput)
 
1097
 
 
1098
Here, we're not submitting any data, so the initial value will be displayed.
 
1099
>>> p = UserRegistration(initial={'username': 'django'}, auto_id=False)
 
1100
>>> print p.as_ul()
 
1101
<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
 
1102
<li>Password: <input type="password" name="password" /></li>
 
1103
>>> p = UserRegistration(initial={'username': 'stephane'}, auto_id=False)
 
1104
>>> print p.as_ul()
 
1105
<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
 
1106
<li>Password: <input type="password" name="password" /></li>
 
1107
 
 
1108
The 'initial' parameter is meaningless if you pass data.
 
1109
>>> p = UserRegistration({}, initial={'username': 'django'}, auto_id=False)
 
1110
>>> print p.as_ul()
 
1111
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1112
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1113
>>> p = UserRegistration({'username': u''}, initial={'username': 'django'}, auto_id=False)
 
1114
>>> print p.as_ul()
 
1115
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1116
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1117
>>> p = UserRegistration({'username': u'foo'}, initial={'username': 'django'}, auto_id=False)
 
1118
>>> print p.as_ul()
 
1119
<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
 
1120
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1121
 
 
1122
A dynamic 'initial' value is *not* used as a fallback if data is not provided.
 
1123
In this example, we don't provide a value for 'username', and the form raises a
 
1124
validation error rather than using the initial value for 'username'.
 
1125
>>> p = UserRegistration({'password': 'secret'}, initial={'username': 'django'})
 
1126
>>> p.errors['username']
 
1127
[u'This field is required.']
 
1128
>>> p.is_valid()
 
1129
False
 
1130
 
 
1131
If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
 
1132
then the latter will get precedence.
 
1133
>>> class UserRegistration(Form):
 
1134
...    username = CharField(max_length=10, initial='django')
 
1135
...    password = CharField(widget=PasswordInput)
 
1136
>>> p = UserRegistration(initial={'username': 'babik'}, auto_id=False)
 
1137
>>> print p.as_ul()
 
1138
<li>Username: <input type="text" name="username" value="babik" maxlength="10" /></li>
 
1139
<li>Password: <input type="password" name="password" /></li>
 
1140
 
 
1141
# Callable initial data ########################################################
 
1142
 
 
1143
The previous technique dealt with raw values as initial data, but it's also
 
1144
possible to specify callable data.
 
1145
 
 
1146
>>> class UserRegistration(Form):
 
1147
...    username = CharField(max_length=10)
 
1148
...    password = CharField(widget=PasswordInput)
 
1149
...    options = MultipleChoiceField(choices=[('f','foo'),('b','bar'),('w','whiz')])
 
1150
 
 
1151
We need to define functions that get called later.
 
1152
>>> def initial_django():
 
1153
...     return 'django'
 
1154
>>> def initial_stephane():
 
1155
...     return 'stephane'
 
1156
>>> def initial_options():
 
1157
...     return ['f','b']
 
1158
>>> def initial_other_options():
 
1159
...     return ['b','w']
 
1160
 
 
1161
 
 
1162
Here, we're not submitting any data, so the initial value will be displayed.
 
1163
>>> p = UserRegistration(initial={'username': initial_django, 'options': initial_options}, auto_id=False)
 
1164
>>> print p.as_ul()
 
1165
<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
 
1166
<li>Password: <input type="password" name="password" /></li>
 
1167
<li>Options: <select multiple="multiple" name="options">
 
1168
<option value="f" selected="selected">foo</option>
 
1169
<option value="b" selected="selected">bar</option>
 
1170
<option value="w">whiz</option>
 
1171
</select></li>
 
1172
 
 
1173
The 'initial' parameter is meaningless if you pass data.
 
1174
>>> p = UserRegistration({}, initial={'username': initial_django, 'options': initial_options}, auto_id=False)
 
1175
>>> print p.as_ul()
 
1176
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1177
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1178
<li><ul class="errorlist"><li>This field is required.</li></ul>Options: <select multiple="multiple" name="options">
 
1179
<option value="f">foo</option>
 
1180
<option value="b">bar</option>
 
1181
<option value="w">whiz</option>
 
1182
</select></li>
 
1183
>>> p = UserRegistration({'username': u''}, initial={'username': initial_django}, auto_id=False)
 
1184
>>> print p.as_ul()
 
1185
<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
 
1186
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1187
<li><ul class="errorlist"><li>This field is required.</li></ul>Options: <select multiple="multiple" name="options">
 
1188
<option value="f">foo</option>
 
1189
<option value="b">bar</option>
 
1190
<option value="w">whiz</option>
 
1191
</select></li>
 
1192
>>> p = UserRegistration({'username': u'foo', 'options':['f','b']}, initial={'username': initial_django}, auto_id=False)
 
1193
>>> print p.as_ul()
 
1194
<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
 
1195
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
1196
<li>Options: <select multiple="multiple" name="options">
 
1197
<option value="f" selected="selected">foo</option>
 
1198
<option value="b" selected="selected">bar</option>
 
1199
<option value="w">whiz</option>
 
1200
</select></li>
 
1201
 
 
1202
A callable 'initial' value is *not* used as a fallback if data is not provided.
 
1203
In this example, we don't provide a value for 'username', and the form raises a
 
1204
validation error rather than using the initial value for 'username'.
 
1205
>>> p = UserRegistration({'password': 'secret'}, initial={'username': initial_django, 'options': initial_options})
 
1206
>>> p.errors['username']
 
1207
[u'This field is required.']
 
1208
>>> p.is_valid()
 
1209
False
 
1210
 
 
1211
If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
 
1212
then the latter will get precedence.
 
1213
>>> class UserRegistration(Form):
 
1214
...    username = CharField(max_length=10, initial=initial_django)
 
1215
...    password = CharField(widget=PasswordInput)
 
1216
...    options = MultipleChoiceField(choices=[('f','foo'),('b','bar'),('w','whiz')], initial=initial_other_options)
 
1217
 
 
1218
>>> p = UserRegistration(auto_id=False)
 
1219
>>> print p.as_ul()
 
1220
<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
 
1221
<li>Password: <input type="password" name="password" /></li>
 
1222
<li>Options: <select multiple="multiple" name="options">
 
1223
<option value="f">foo</option>
 
1224
<option value="b" selected="selected">bar</option>
 
1225
<option value="w" selected="selected">whiz</option>
 
1226
</select></li>
 
1227
>>> p = UserRegistration(initial={'username': initial_stephane, 'options': initial_options}, auto_id=False)
 
1228
>>> print p.as_ul()
 
1229
<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
 
1230
<li>Password: <input type="password" name="password" /></li>
 
1231
<li>Options: <select multiple="multiple" name="options">
 
1232
<option value="f" selected="selected">foo</option>
 
1233
<option value="b" selected="selected">bar</option>
 
1234
<option value="w">whiz</option>
 
1235
</select></li>
 
1236
 
 
1237
# Help text ###################################################################
 
1238
 
 
1239
You can specify descriptive text for a field by using the 'help_text' argument
 
1240
to a Field class. This help text is displayed when a Form is rendered.
 
1241
>>> class UserRegistration(Form):
 
1242
...    username = CharField(max_length=10, help_text='e.g., user@example.com')
 
1243
...    password = CharField(widget=PasswordInput, help_text='Choose wisely.')
 
1244
>>> p = UserRegistration(auto_id=False)
 
1245
>>> print p.as_ul()
 
1246
<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
 
1247
<li>Password: <input type="password" name="password" /> Choose wisely.</li>
 
1248
>>> print p.as_p()
 
1249
<p>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p>
 
1250
<p>Password: <input type="password" name="password" /> Choose wisely.</p>
 
1251
>>> print p.as_table()
 
1252
<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr>
 
1253
<tr><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr>
 
1254
 
 
1255
The help text is displayed whether or not data is provided for the form.
 
1256
>>> p = UserRegistration({'username': u'foo'}, auto_id=False)
 
1257
>>> print p.as_ul()
 
1258
<li>Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li>
 
1259
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li>
 
1260
 
 
1261
help_text is not displayed for hidden fields. It can be used for documentation
 
1262
purposes, though.
 
1263
>>> class UserRegistration(Form):
 
1264
...    username = CharField(max_length=10, help_text='e.g., user@example.com')
 
1265
...    password = CharField(widget=PasswordInput)
 
1266
...    next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
 
1267
>>> p = UserRegistration(auto_id=False)
 
1268
>>> print p.as_ul()
 
1269
<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
 
1270
<li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>
 
1271
 
 
1272
Help text can include arbitrary Unicode characters.
 
1273
>>> class UserRegistration(Form):
 
1274
...    username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ')
 
1275
>>> p = UserRegistration(auto_id=False)
 
1276
>>> p.as_ul()
 
1277
u'<li>Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>'
 
1278
 
 
1279
# Subclassing forms ###########################################################
 
1280
 
 
1281
You can subclass a Form to add fields. The resulting form subclass will have
 
1282
all of the fields of the parent Form, plus whichever fields you define in the
 
1283
subclass.
 
1284
>>> class Person(Form):
 
1285
...     first_name = CharField()
 
1286
...     last_name = CharField()
 
1287
...     birthday = DateField()
 
1288
>>> class Musician(Person):
 
1289
...     instrument = CharField()
 
1290
>>> p = Person(auto_id=False)
 
1291
>>> print p.as_ul()
 
1292
<li>First name: <input type="text" name="first_name" /></li>
 
1293
<li>Last name: <input type="text" name="last_name" /></li>
 
1294
<li>Birthday: <input type="text" name="birthday" /></li>
 
1295
>>> m = Musician(auto_id=False)
 
1296
>>> print m.as_ul()
 
1297
<li>First name: <input type="text" name="first_name" /></li>
 
1298
<li>Last name: <input type="text" name="last_name" /></li>
 
1299
<li>Birthday: <input type="text" name="birthday" /></li>
 
1300
<li>Instrument: <input type="text" name="instrument" /></li>
 
1301
 
 
1302
Yes, you can subclass multiple forms. The fields are added in the order in
 
1303
which the parent classes are listed.
 
1304
>>> class Person(Form):
 
1305
...     first_name = CharField()
 
1306
...     last_name = CharField()
 
1307
...     birthday = DateField()
 
1308
>>> class Instrument(Form):
 
1309
...     instrument = CharField()
 
1310
>>> class Beatle(Person, Instrument):
 
1311
...     haircut_type = CharField()
 
1312
>>> b = Beatle(auto_id=False)
 
1313
>>> print b.as_ul()
 
1314
<li>First name: <input type="text" name="first_name" /></li>
 
1315
<li>Last name: <input type="text" name="last_name" /></li>
 
1316
<li>Birthday: <input type="text" name="birthday" /></li>
 
1317
<li>Instrument: <input type="text" name="instrument" /></li>
 
1318
<li>Haircut type: <input type="text" name="haircut_type" /></li>
 
1319
 
 
1320
# Forms with prefixes #########################################################
 
1321
 
 
1322
Sometimes it's necessary to have multiple forms display on the same HTML page,
 
1323
or multiple copies of the same form. We can accomplish this with form prefixes.
 
1324
Pass the keyword argument 'prefix' to the Form constructor to use this feature.
 
1325
This value will be prepended to each HTML form field name. One way to think
 
1326
about this is "namespaces for HTML forms". Notice that in the data argument,
 
1327
each field's key has the prefix, in this case 'person1', prepended to the
 
1328
actual field name.
 
1329
>>> class Person(Form):
 
1330
...     first_name = CharField()
 
1331
...     last_name = CharField()
 
1332
...     birthday = DateField()
 
1333
>>> data = {
 
1334
...     'person1-first_name': u'John',
 
1335
...     'person1-last_name': u'Lennon',
 
1336
...     'person1-birthday': u'1940-10-9'
 
1337
... }
 
1338
>>> p = Person(data, prefix='person1')
 
1339
>>> print p.as_ul()
 
1340
<li><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /></li>
 
1341
<li><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /></li>
 
1342
<li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li>
 
1343
>>> print p['first_name']
 
1344
<input type="text" name="person1-first_name" value="John" id="id_person1-first_name" />
 
1345
>>> print p['last_name']
 
1346
<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" />
 
1347
>>> print p['birthday']
 
1348
<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" />
 
1349
>>> p.errors
 
1350
{}
 
1351
>>> p.is_valid()
 
1352
True
 
1353
>>> p.cleaned_data['first_name']
 
1354
u'John'
 
1355
>>> p.cleaned_data['last_name']
 
1356
u'Lennon'
 
1357
>>> p.cleaned_data['birthday']
 
1358
datetime.date(1940, 10, 9)
 
1359
 
 
1360
Let's try submitting some bad data to make sure form.errors and field.errors
 
1361
work as expected.
 
1362
>>> data = {
 
1363
...     'person1-first_name': u'',
 
1364
...     'person1-last_name': u'',
 
1365
...     'person1-birthday': u''
 
1366
... }
 
1367
>>> p = Person(data, prefix='person1')
 
1368
>>> p.errors['first_name']
 
1369
[u'This field is required.']
 
1370
>>> p.errors['last_name']
 
1371
[u'This field is required.']
 
1372
>>> p.errors['birthday']
 
1373
[u'This field is required.']
 
1374
>>> p['first_name'].errors
 
1375
[u'This field is required.']
 
1376
>>> p['person1-first_name'].errors
 
1377
Traceback (most recent call last):
 
1378
...
 
1379
KeyError: "Key 'person1-first_name' not found in Form"
 
1380
 
 
1381
In this example, the data doesn't have a prefix, but the form requires it, so
 
1382
the form doesn't "see" the fields.
 
1383
>>> data = {
 
1384
...     'first_name': u'John',
 
1385
...     'last_name': u'Lennon',
 
1386
...     'birthday': u'1940-10-9'
 
1387
... }
 
1388
>>> p = Person(data, prefix='person1')
 
1389
>>> p.errors['first_name']
 
1390
[u'This field is required.']
 
1391
>>> p.errors['last_name']
 
1392
[u'This field is required.']
 
1393
>>> p.errors['birthday']
 
1394
[u'This field is required.']
 
1395
 
 
1396
With prefixes, a single data dictionary can hold data for multiple instances
 
1397
of the same form.
 
1398
>>> data = {
 
1399
...     'person1-first_name': u'John',
 
1400
...     'person1-last_name': u'Lennon',
 
1401
...     'person1-birthday': u'1940-10-9',
 
1402
...     'person2-first_name': u'Jim',
 
1403
...     'person2-last_name': u'Morrison',
 
1404
...     'person2-birthday': u'1943-12-8'
 
1405
... }
 
1406
>>> p1 = Person(data, prefix='person1')
 
1407
>>> p1.is_valid()
 
1408
True
 
1409
>>> p1.cleaned_data['first_name']
 
1410
u'John'
 
1411
>>> p1.cleaned_data['last_name']
 
1412
u'Lennon'
 
1413
>>> p1.cleaned_data['birthday']
 
1414
datetime.date(1940, 10, 9)
 
1415
>>> p2 = Person(data, prefix='person2')
 
1416
>>> p2.is_valid()
 
1417
True
 
1418
>>> p2.cleaned_data['first_name']
 
1419
u'Jim'
 
1420
>>> p2.cleaned_data['last_name']
 
1421
u'Morrison'
 
1422
>>> p2.cleaned_data['birthday']
 
1423
datetime.date(1943, 12, 8)
 
1424
 
 
1425
By default, forms append a hyphen between the prefix and the field name, but a
 
1426
form can alter that behavior by implementing the add_prefix() method. This
 
1427
method takes a field name and returns the prefixed field, according to
 
1428
self.prefix.
 
1429
>>> class Person(Form):
 
1430
...     first_name = CharField()
 
1431
...     last_name = CharField()
 
1432
...     birthday = DateField()
 
1433
...     def add_prefix(self, field_name):
 
1434
...         return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name
 
1435
>>> p = Person(prefix='foo')
 
1436
>>> print p.as_ul()
 
1437
<li><label for="id_foo-prefix-first_name">First name:</label> <input type="text" name="foo-prefix-first_name" id="id_foo-prefix-first_name" /></li>
 
1438
<li><label for="id_foo-prefix-last_name">Last name:</label> <input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" /></li>
 
1439
<li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li>
 
1440
>>> data = {
 
1441
...     'foo-prefix-first_name': u'John',
 
1442
...     'foo-prefix-last_name': u'Lennon',
 
1443
...     'foo-prefix-birthday': u'1940-10-9'
 
1444
... }
 
1445
>>> p = Person(data, prefix='foo')
 
1446
>>> p.is_valid()
 
1447
True
 
1448
>>> p.cleaned_data['first_name']
 
1449
u'John'
 
1450
>>> p.cleaned_data['last_name']
 
1451
u'Lennon'
 
1452
>>> p.cleaned_data['birthday']
 
1453
datetime.date(1940, 10, 9)
 
1454
 
 
1455
# Forms with NullBooleanFields ################################################
 
1456
 
 
1457
NullBooleanField is a bit of a special case because its presentation (widget)
 
1458
is different than its data. This is handled transparently, though.
 
1459
 
 
1460
>>> class Person(Form):
 
1461
...     name = CharField()
 
1462
...     is_cool = NullBooleanField()
 
1463
>>> p = Person({'name': u'Joe'}, auto_id=False)
 
1464
>>> print p['is_cool']
 
1465
<select name="is_cool">
 
1466
<option value="1" selected="selected">Unknown</option>
 
1467
<option value="2">Yes</option>
 
1468
<option value="3">No</option>
 
1469
</select>
 
1470
>>> p = Person({'name': u'Joe', 'is_cool': u'1'}, auto_id=False)
 
1471
>>> print p['is_cool']
 
1472
<select name="is_cool">
 
1473
<option value="1" selected="selected">Unknown</option>
 
1474
<option value="2">Yes</option>
 
1475
<option value="3">No</option>
 
1476
</select>
 
1477
>>> p = Person({'name': u'Joe', 'is_cool': u'2'}, auto_id=False)
 
1478
>>> print p['is_cool']
 
1479
<select name="is_cool">
 
1480
<option value="1">Unknown</option>
 
1481
<option value="2" selected="selected">Yes</option>
 
1482
<option value="3">No</option>
 
1483
</select>
 
1484
>>> p = Person({'name': u'Joe', 'is_cool': u'3'}, auto_id=False)
 
1485
>>> print p['is_cool']
 
1486
<select name="is_cool">
 
1487
<option value="1">Unknown</option>
 
1488
<option value="2">Yes</option>
 
1489
<option value="3" selected="selected">No</option>
 
1490
</select>
 
1491
>>> p = Person({'name': u'Joe', 'is_cool': True}, auto_id=False)
 
1492
>>> print p['is_cool']
 
1493
<select name="is_cool">
 
1494
<option value="1">Unknown</option>
 
1495
<option value="2" selected="selected">Yes</option>
 
1496
<option value="3">No</option>
 
1497
</select>
 
1498
>>> p = Person({'name': u'Joe', 'is_cool': False}, auto_id=False)
 
1499
>>> print p['is_cool']
 
1500
<select name="is_cool">
 
1501
<option value="1">Unknown</option>
 
1502
<option value="2">Yes</option>
 
1503
<option value="3" selected="selected">No</option>
 
1504
</select>
 
1505
 
 
1506
# Forms with FileFields ################################################
 
1507
 
 
1508
FileFields are a special case because they take their data from the request.FILES,
 
1509
not request.POST.
 
1510
 
 
1511
>>> class FileForm(Form):
 
1512
...     file1 = FileField()
 
1513
>>> f = FileForm(auto_id=False)
 
1514
>>> print f
 
1515
<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
 
1516
 
 
1517
>>> f = FileForm(data={}, files={}, auto_id=False)
 
1518
>>> print f
 
1519
<tr><th>File1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="file" name="file1" /></td></tr>
 
1520
 
 
1521
>>> f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', '')}, auto_id=False)
 
1522
>>> print f
 
1523
<tr><th>File1:</th><td><ul class="errorlist"><li>The submitted file is empty.</li></ul><input type="file" name="file1" /></td></tr>
 
1524
 
 
1525
>>> f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False)
 
1526
>>> print f
 
1527
<tr><th>File1:</th><td><ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul><input type="file" name="file1" /></td></tr>
 
1528
 
 
1529
>>> f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', 'some content')}, auto_id=False)
 
1530
>>> print f
 
1531
<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
 
1532
>>> f.is_valid()
 
1533
True
 
1534
 
 
1535
>>> f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')}, auto_id=False)
 
1536
>>> print f
 
1537
<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
 
1538
 
 
1539
# Basic form processing in a view #############################################
 
1540
 
 
1541
>>> from django.template import Template, Context
 
1542
>>> class UserRegistration(Form):
 
1543
...    username = CharField(max_length=10)
 
1544
...    password1 = CharField(widget=PasswordInput)
 
1545
...    password2 = CharField(widget=PasswordInput)
 
1546
...    def clean(self):
 
1547
...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
 
1548
...            raise ValidationError(u'Please make sure your passwords match.')
 
1549
...        return self.cleaned_data
 
1550
>>> def my_function(method, post_data):
 
1551
...     if method == 'POST':
 
1552
...         form = UserRegistration(post_data, auto_id=False)
 
1553
...     else:
 
1554
...         form = UserRegistration(auto_id=False)
 
1555
...     if form.is_valid():
 
1556
...         return 'VALID: %r' % form.cleaned_data
 
1557
...     t = Template('<form action="" method="post">\n<table>\n{{ form }}\n</table>\n<input type="submit" />\n</form>')
 
1558
...     return t.render(Context({'form': form}))
 
1559
 
 
1560
Case 1: GET (an empty form, with no errors).
 
1561
>>> print my_function('GET', {})
 
1562
<form action="" method="post">
 
1563
<table>
 
1564
<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr>
 
1565
<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
 
1566
<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
 
1567
</table>
 
1568
<input type="submit" />
 
1569
</form>
 
1570
 
 
1571
Case 2: POST with erroneous data (a redisplayed form, with errors).
 
1572
>>> print my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'})
 
1573
<form action="" method="post">
 
1574
<table>
 
1575
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
 
1576
<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
 
1577
<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
 
1578
<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
 
1579
</table>
 
1580
<input type="submit" />
 
1581
</form>
 
1582
 
 
1583
Case 3: POST with valid data (the success message).
 
1584
>>> print my_function('POST', {'username': 'adrian', 'password1': 'secret', 'password2': 'secret'})
 
1585
VALID: {'username': u'adrian', 'password1': u'secret', 'password2': u'secret'}
 
1586
 
 
1587
# Some ideas for using templates with forms ###################################
 
1588
 
 
1589
>>> class UserRegistration(Form):
 
1590
...    username = CharField(max_length=10, help_text="Good luck picking a username that doesn't already exist.")
 
1591
...    password1 = CharField(widget=PasswordInput)
 
1592
...    password2 = CharField(widget=PasswordInput)
 
1593
...    def clean(self):
 
1594
...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
 
1595
...            raise ValidationError(u'Please make sure your passwords match.')
 
1596
...        return self.cleaned_data
 
1597
 
 
1598
You have full flexibility in displaying form fields in a template. Just pass a
 
1599
Form instance to the template, and use "dot" access to refer to individual
 
1600
fields. Note, however, that this flexibility comes with the responsibility of
 
1601
displaying all the errors, including any that might not be associated with a
 
1602
particular field.
 
1603
>>> t = Template('''<form action="">
 
1604
... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 
1605
... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 
1606
... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 
1607
... <input type="submit" />
 
1608
... </form>''')
 
1609
>>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
 
1610
<form action="">
 
1611
<p><label>Your username: <input type="text" name="username" maxlength="10" /></label></p>
 
1612
<p><label>Password: <input type="password" name="password1" /></label></p>
 
1613
<p><label>Password (again): <input type="password" name="password2" /></label></p>
 
1614
<input type="submit" />
 
1615
</form>
 
1616
>>> print t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)}))
 
1617
<form action="">
 
1618
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
 
1619
<ul class="errorlist"><li>This field is required.</li></ul><p><label>Password: <input type="password" name="password1" /></label></p>
 
1620
<ul class="errorlist"><li>This field is required.</li></ul><p><label>Password (again): <input type="password" name="password2" /></label></p>
 
1621
<input type="submit" />
 
1622
</form>
 
1623
 
 
1624
Use form.[field].label to output a field's label. You can specify the label for
 
1625
a field by using the 'label' argument to a Field class. If you don't specify
 
1626
'label', Django will use the field name with underscores converted to spaces,
 
1627
and the initial letter capitalized.
 
1628
>>> t = Template('''<form action="">
 
1629
... <p><label>{{ form.username.label }}: {{ form.username }}</label></p>
 
1630
... <p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>
 
1631
... <p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>
 
1632
... <input type="submit" />
 
1633
... </form>''')
 
1634
>>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
 
1635
<form action="">
 
1636
<p><label>Username: <input type="text" name="username" maxlength="10" /></label></p>
 
1637
<p><label>Password1: <input type="password" name="password1" /></label></p>
 
1638
<p><label>Password2: <input type="password" name="password2" /></label></p>
 
1639
<input type="submit" />
 
1640
</form>
 
1641
 
 
1642
User form.[field].label_tag to output a field's label with a <label> tag
 
1643
wrapped around it, but *only* if the given field has an "id" attribute.
 
1644
Recall from above that passing the "auto_id" argument to a Form gives each
 
1645
field an "id" attribute.
 
1646
>>> t = Template('''<form action="">
 
1647
... <p>{{ form.username.label_tag }}: {{ form.username }}</p>
 
1648
... <p>{{ form.password1.label_tag }}: {{ form.password1 }}</p>
 
1649
... <p>{{ form.password2.label_tag }}: {{ form.password2 }}</p>
 
1650
... <input type="submit" />
 
1651
... </form>''')
 
1652
>>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
 
1653
<form action="">
 
1654
<p>Username: <input type="text" name="username" maxlength="10" /></p>
 
1655
<p>Password1: <input type="password" name="password1" /></p>
 
1656
<p>Password2: <input type="password" name="password2" /></p>
 
1657
<input type="submit" />
 
1658
</form>
 
1659
>>> print t.render(Context({'form': UserRegistration(auto_id='id_%s')}))
 
1660
<form action="">
 
1661
<p><label for="id_username">Username</label>: <input id="id_username" type="text" name="username" maxlength="10" /></p>
 
1662
<p><label for="id_password1">Password1</label>: <input type="password" name="password1" id="id_password1" /></p>
 
1663
<p><label for="id_password2">Password2</label>: <input type="password" name="password2" id="id_password2" /></p>
 
1664
<input type="submit" />
 
1665
</form>
 
1666
 
 
1667
User form.[field].help_text to output a field's help text. If the given field
 
1668
does not have help text, nothing will be output.
 
1669
>>> t = Template('''<form action="">
 
1670
... <p>{{ form.username.label_tag }}: {{ form.username }}<br />{{ form.username.help_text }}</p>
 
1671
... <p>{{ form.password1.label_tag }}: {{ form.password1 }}</p>
 
1672
... <p>{{ form.password2.label_tag }}: {{ form.password2 }}</p>
 
1673
... <input type="submit" />
 
1674
... </form>''')
 
1675
>>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
 
1676
<form action="">
 
1677
<p>Username: <input type="text" name="username" maxlength="10" /><br />Good luck picking a username that doesn&#39;t already exist.</p>
 
1678
<p>Password1: <input type="password" name="password1" /></p>
 
1679
<p>Password2: <input type="password" name="password2" /></p>
 
1680
<input type="submit" />
 
1681
</form>
 
1682
>>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)}))
 
1683
u''
 
1684
 
 
1685
The label_tag() method takes an optional attrs argument: a dictionary of HTML
 
1686
attributes to add to the <label> tag.
 
1687
>>> f = UserRegistration(auto_id='id_%s')
 
1688
>>> for bf in f:
 
1689
...     print bf.label_tag(attrs={'class': 'pretty'})
 
1690
<label for="id_username" class="pretty">Username</label>
 
1691
<label for="id_password1" class="pretty">Password1</label>
 
1692
<label for="id_password2" class="pretty">Password2</label>
 
1693
 
 
1694
To display the errors that aren't associated with a particular field -- e.g.,
 
1695
the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
 
1696
template. If used on its own, it is displayed as a <ul> (or an empty string, if
 
1697
the list of errors is empty). You can also use it in {% if %} statements.
 
1698
>>> t = Template('''<form action="">
 
1699
... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 
1700
... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 
1701
... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 
1702
... <input type="submit" />
 
1703
... </form>''')
 
1704
>>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
 
1705
<form action="">
 
1706
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
 
1707
<p><label>Password: <input type="password" name="password1" value="foo" /></label></p>
 
1708
<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p>
 
1709
<input type="submit" />
 
1710
</form>
 
1711
>>> t = Template('''<form action="">
 
1712
... {{ form.non_field_errors }}
 
1713
... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 
1714
... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 
1715
... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 
1716
... <input type="submit" />
 
1717
... </form>''')
 
1718
>>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
 
1719
<form action="">
 
1720
<ul class="errorlist"><li>Please make sure your passwords match.</li></ul>
 
1721
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
 
1722
<p><label>Password: <input type="password" name="password1" value="foo" /></label></p>
 
1723
<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p>
 
1724
<input type="submit" />
 
1725
</form>
 
1726
 
 
1727
 
 
1728
# The empty_permitted attribute ##############################################
 
1729
 
 
1730
Sometimes (pretty much in formsets) we want to allow a form to pass validation
 
1731
if it is completely empty. We can accomplish this by using the empty_permitted
 
1732
agrument to a form constructor.
 
1733
 
 
1734
>>> class SongForm(Form):
 
1735
...     artist = CharField()
 
1736
...     name = CharField()
 
1737
 
 
1738
First let's show what happens id empty_permitted=False (the default):
 
1739
 
 
1740
>>> data = {'artist': '', 'song': ''}
 
1741
 
 
1742
>>> form = SongForm(data, empty_permitted=False)
 
1743
>>> form.is_valid()
 
1744
False
 
1745
>>> form.errors
 
1746
{'name': [u'This field is required.'], 'artist': [u'This field is required.']}
 
1747
>>> form.cleaned_data
 
1748
Traceback (most recent call last):
 
1749
...
 
1750
AttributeError: 'SongForm' object has no attribute 'cleaned_data'
 
1751
 
 
1752
 
 
1753
Now let's show what happens when empty_permitted=True and the form is empty.
 
1754
 
 
1755
>>> form = SongForm(data, empty_permitted=True)
 
1756
>>> form.is_valid()
 
1757
True
 
1758
>>> form.errors
 
1759
{}
 
1760
>>> form.cleaned_data
 
1761
{}
 
1762
 
 
1763
But if we fill in data for one of the fields, the form is no longer empty and
 
1764
the whole thing must pass validation.
 
1765
 
 
1766
>>> data = {'artist': 'The Doors', 'song': ''}
 
1767
>>> form = SongForm(data, empty_permitted=False)
 
1768
>>> form.is_valid()
 
1769
False
 
1770
>>> form.errors
 
1771
{'name': [u'This field is required.']}
 
1772
>>> form.cleaned_data
 
1773
Traceback (most recent call last):
 
1774
...
 
1775
AttributeError: 'SongForm' object has no attribute 'cleaned_data'
 
1776
 
 
1777
If a field is not given in the data then None is returned for its data. Lets
 
1778
make sure that when checking for empty_permitted that None is treated
 
1779
accordingly.
 
1780
 
 
1781
>>> data = {'artist': None, 'song': ''}
 
1782
>>> form = SongForm(data, empty_permitted=True)
 
1783
>>> form.is_valid()
 
1784
True
 
1785
 
 
1786
However, we *really* need to be sure we are checking for None as any data in
 
1787
initial that returns False on a boolean call needs to be treated literally.
 
1788
 
 
1789
>>> class PriceForm(Form):
 
1790
...     amount = FloatField()
 
1791
...     qty = IntegerField()
 
1792
 
 
1793
>>> data = {'amount': '0.0', 'qty': ''}
 
1794
>>> form = PriceForm(data, initial={'amount': 0.0}, empty_permitted=True)
 
1795
>>> form.is_valid()
 
1796
True
 
1797
 
 
1798
# Extracting hidden and visible fields ######################################
 
1799
 
 
1800
>>> class SongForm(Form):
 
1801
...     token = CharField(widget=HiddenInput)
 
1802
...     artist = CharField()
 
1803
...     name = CharField()
 
1804
>>> form = SongForm()
 
1805
>>> [f.name for f in form.hidden_fields()]
 
1806
['token']
 
1807
>>> [f.name for f in form.visible_fields()]
 
1808
['artist', 'name']
 
1809
 
 
1810
"""