1
# -*- coding: utf-8 -*-
3
>>> from django.forms import *
4
>>> from django.utils.encoding import force_unicode
8
>>> from decimal import Decimal
14
The forms library comes with some extra, higher-level Field and Widget
15
classes that demonstrate some of the library's abilities.
17
# SelectDateWidget ############################################################
19
>>> from django.forms.extras import SelectDateWidget
20
>>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
21
>>> print w.render('mydate', '')
22
<select name="mydate_month" id="id_mydate_month">
23
<option value="0">---</option>
24
<option value="1">January</option>
25
<option value="2">February</option>
26
<option value="3">March</option>
27
<option value="4">April</option>
28
<option value="5">May</option>
29
<option value="6">June</option>
30
<option value="7">July</option>
31
<option value="8">August</option>
32
<option value="9">September</option>
33
<option value="10">October</option>
34
<option value="11">November</option>
35
<option value="12">December</option>
37
<select name="mydate_day" id="id_mydate_day">
38
<option value="0">---</option>
39
<option value="1">1</option>
40
<option value="2">2</option>
41
<option value="3">3</option>
42
<option value="4">4</option>
43
<option value="5">5</option>
44
<option value="6">6</option>
45
<option value="7">7</option>
46
<option value="8">8</option>
47
<option value="9">9</option>
48
<option value="10">10</option>
49
<option value="11">11</option>
50
<option value="12">12</option>
51
<option value="13">13</option>
52
<option value="14">14</option>
53
<option value="15">15</option>
54
<option value="16">16</option>
55
<option value="17">17</option>
56
<option value="18">18</option>
57
<option value="19">19</option>
58
<option value="20">20</option>
59
<option value="21">21</option>
60
<option value="22">22</option>
61
<option value="23">23</option>
62
<option value="24">24</option>
63
<option value="25">25</option>
64
<option value="26">26</option>
65
<option value="27">27</option>
66
<option value="28">28</option>
67
<option value="29">29</option>
68
<option value="30">30</option>
69
<option value="31">31</option>
71
<select name="mydate_year" id="id_mydate_year">
72
<option value="0">---</option>
73
<option value="2007">2007</option>
74
<option value="2008">2008</option>
75
<option value="2009">2009</option>
76
<option value="2010">2010</option>
77
<option value="2011">2011</option>
78
<option value="2012">2012</option>
79
<option value="2013">2013</option>
80
<option value="2014">2014</option>
81
<option value="2015">2015</option>
82
<option value="2016">2016</option>
84
>>> w.render('mydate', None) == w.render('mydate', '')
86
>>> print w.render('mydate', '2010-04-15')
87
<select name="mydate_month" id="id_mydate_month">
88
<option value="1">January</option>
89
<option value="2">February</option>
90
<option value="3">March</option>
91
<option value="4" selected="selected">April</option>
92
<option value="5">May</option>
93
<option value="6">June</option>
94
<option value="7">July</option>
95
<option value="8">August</option>
96
<option value="9">September</option>
97
<option value="10">October</option>
98
<option value="11">November</option>
99
<option value="12">December</option>
101
<select name="mydate_day" id="id_mydate_day">
102
<option value="1">1</option>
103
<option value="2">2</option>
104
<option value="3">3</option>
105
<option value="4">4</option>
106
<option value="5">5</option>
107
<option value="6">6</option>
108
<option value="7">7</option>
109
<option value="8">8</option>
110
<option value="9">9</option>
111
<option value="10">10</option>
112
<option value="11">11</option>
113
<option value="12">12</option>
114
<option value="13">13</option>
115
<option value="14">14</option>
116
<option value="15" selected="selected">15</option>
117
<option value="16">16</option>
118
<option value="17">17</option>
119
<option value="18">18</option>
120
<option value="19">19</option>
121
<option value="20">20</option>
122
<option value="21">21</option>
123
<option value="22">22</option>
124
<option value="23">23</option>
125
<option value="24">24</option>
126
<option value="25">25</option>
127
<option value="26">26</option>
128
<option value="27">27</option>
129
<option value="28">28</option>
130
<option value="29">29</option>
131
<option value="30">30</option>
132
<option value="31">31</option>
134
<select name="mydate_year" id="id_mydate_year">
135
<option value="2007">2007</option>
136
<option value="2008">2008</option>
137
<option value="2009">2009</option>
138
<option value="2010" selected="selected">2010</option>
139
<option value="2011">2011</option>
140
<option value="2012">2012</option>
141
<option value="2013">2013</option>
142
<option value="2014">2014</option>
143
<option value="2015">2015</option>
144
<option value="2016">2016</option>
147
Accepts a datetime or a string:
149
>>> w.render('mydate', datetime.date(2010, 4, 15)) == w.render('mydate', '2010-04-15')
152
Invalid dates still render the failed date:
153
>>> print w.render('mydate', '2010-02-31')
154
<select name="mydate_month" id="id_mydate_month">
155
<option value="1">January</option>
156
<option value="2" selected="selected">February</option>
157
<option value="3">March</option>
158
<option value="4">April</option>
159
<option value="5">May</option>
160
<option value="6">June</option>
161
<option value="7">July</option>
162
<option value="8">August</option>
163
<option value="9">September</option>
164
<option value="10">October</option>
165
<option value="11">November</option>
166
<option value="12">December</option>
168
<select name="mydate_day" id="id_mydate_day">
169
<option value="1">1</option>
170
<option value="2">2</option>
171
<option value="3">3</option>
172
<option value="4">4</option>
173
<option value="5">5</option>
174
<option value="6">6</option>
175
<option value="7">7</option>
176
<option value="8">8</option>
177
<option value="9">9</option>
178
<option value="10">10</option>
179
<option value="11">11</option>
180
<option value="12">12</option>
181
<option value="13">13</option>
182
<option value="14">14</option>
183
<option value="15">15</option>
184
<option value="16">16</option>
185
<option value="17">17</option>
186
<option value="18">18</option>
187
<option value="19">19</option>
188
<option value="20">20</option>
189
<option value="21">21</option>
190
<option value="22">22</option>
191
<option value="23">23</option>
192
<option value="24">24</option>
193
<option value="25">25</option>
194
<option value="26">26</option>
195
<option value="27">27</option>
196
<option value="28">28</option>
197
<option value="29">29</option>
198
<option value="30">30</option>
199
<option value="31" selected="selected">31</option>
201
<select name="mydate_year" id="id_mydate_year">
202
<option value="2007">2007</option>
203
<option value="2008">2008</option>
204
<option value="2009">2009</option>
205
<option value="2010" selected="selected">2010</option>
206
<option value="2011">2011</option>
207
<option value="2012">2012</option>
208
<option value="2013">2013</option>
209
<option value="2014">2014</option>
210
<option value="2015">2015</option>
211
<option value="2016">2016</option>
214
Using a SelectDateWidget in a form:
216
>>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
217
>>> print w.render('mydate', '')
218
<select name="mydate_month" id="id_mydate_month">
219
<option value="0">---</option>
220
<option value="1">January</option>
221
<option value="2">February</option>
222
<option value="3">March</option>
223
<option value="4">April</option>
224
<option value="5">May</option>
225
<option value="6">June</option>
226
<option value="7">July</option>
227
<option value="8">August</option>
228
<option value="9">September</option>
229
<option value="10">October</option>
230
<option value="11">November</option>
231
<option value="12">December</option>
233
<select name="mydate_day" id="id_mydate_day">
234
<option value="0">---</option>
235
<option value="1">1</option>
236
<option value="2">2</option>
237
<option value="3">3</option>
238
<option value="4">4</option>
239
<option value="5">5</option>
240
<option value="6">6</option>
241
<option value="7">7</option>
242
<option value="8">8</option>
243
<option value="9">9</option>
244
<option value="10">10</option>
245
<option value="11">11</option>
246
<option value="12">12</option>
247
<option value="13">13</option>
248
<option value="14">14</option>
249
<option value="15">15</option>
250
<option value="16">16</option>
251
<option value="17">17</option>
252
<option value="18">18</option>
253
<option value="19">19</option>
254
<option value="20">20</option>
255
<option value="21">21</option>
256
<option value="22">22</option>
257
<option value="23">23</option>
258
<option value="24">24</option>
259
<option value="25">25</option>
260
<option value="26">26</option>
261
<option value="27">27</option>
262
<option value="28">28</option>
263
<option value="29">29</option>
264
<option value="30">30</option>
265
<option value="31">31</option>
267
<select name="mydate_year" id="id_mydate_year">
268
<option value="0">---</option>
269
<option value="2007">2007</option>
270
<option value="2008">2008</option>
271
<option value="2009">2009</option>
272
<option value="2010">2010</option>
273
<option value="2011">2011</option>
274
<option value="2012">2012</option>
275
<option value="2013">2013</option>
276
<option value="2014">2014</option>
277
<option value="2015">2015</option>
278
<option value="2016">2016</option>
280
>>> print w.render('mydate', '2010-04-15')
281
<select name="mydate_month" id="id_mydate_month">
282
<option value="0">---</option>
283
<option value="1">January</option>
284
<option value="2">February</option>
285
<option value="3">March</option>
286
<option value="4" selected="selected">April</option>
287
<option value="5">May</option>
288
<option value="6">June</option>
289
<option value="7">July</option>
290
<option value="8">August</option>
291
<option value="9">September</option>
292
<option value="10">October</option>
293
<option value="11">November</option>
294
<option value="12">December</option>
296
<select name="mydate_day" id="id_mydate_day">
297
<option value="0">---</option>
298
<option value="1">1</option>
299
<option value="2">2</option>
300
<option value="3">3</option>
301
<option value="4">4</option>
302
<option value="5">5</option>
303
<option value="6">6</option>
304
<option value="7">7</option>
305
<option value="8">8</option>
306
<option value="9">9</option>
307
<option value="10">10</option>
308
<option value="11">11</option>
309
<option value="12">12</option>
310
<option value="13">13</option>
311
<option value="14">14</option>
312
<option value="15" selected="selected">15</option>
313
<option value="16">16</option>
314
<option value="17">17</option>
315
<option value="18">18</option>
316
<option value="19">19</option>
317
<option value="20">20</option>
318
<option value="21">21</option>
319
<option value="22">22</option>
320
<option value="23">23</option>
321
<option value="24">24</option>
322
<option value="25">25</option>
323
<option value="26">26</option>
324
<option value="27">27</option>
325
<option value="28">28</option>
326
<option value="29">29</option>
327
<option value="30">30</option>
328
<option value="31">31</option>
330
<select name="mydate_year" id="id_mydate_year">
331
<option value="0">---</option>
332
<option value="2007">2007</option>
333
<option value="2008">2008</option>
334
<option value="2009">2009</option>
335
<option value="2010" selected="selected">2010</option>
336
<option value="2011">2011</option>
337
<option value="2012">2012</option>
338
<option value="2013">2013</option>
339
<option value="2014">2014</option>
340
<option value="2015">2015</option>
341
<option value="2016">2016</option>
343
>>> class GetDate(Form):
344
... mydate = DateField(widget=SelectDateWidget)
345
>>> a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'})
346
>>> print a.is_valid()
348
>>> print a.cleaned_data['mydate']
351
As with any widget that implements get_value_from_datadict,
352
we must be prepared to accept the input from the "as_hidden"
355
>>> print a['mydate'].as_hidden()
356
<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />
357
>>> b=GetDate({'mydate':'2008-4-1'})
358
>>> print b.is_valid()
360
>>> print b.cleaned_data['mydate']
366
>>> from django.utils import translation
367
>>> translation.activate('nl')
368
>>> from django.conf import settings
369
>>> settings.USE_L10N=True
371
>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
374
>>> print w.render('date', '13-08-2010')
375
<select name="date_day" id="id_date_day">
376
<option value="0">---</option>
377
<option value="1">1</option>
378
<option value="2">2</option>
379
<option value="3">3</option>
380
<option value="4">4</option>
381
<option value="5">5</option>
382
<option value="6">6</option>
383
<option value="7">7</option>
384
<option value="8">8</option>
385
<option value="9">9</option>
386
<option value="10">10</option>
387
<option value="11">11</option>
388
<option value="12">12</option>
389
<option value="13" selected="selected">13</option>
390
<option value="14">14</option>
391
<option value="15">15</option>
392
<option value="16">16</option>
393
<option value="17">17</option>
394
<option value="18">18</option>
395
<option value="19">19</option>
396
<option value="20">20</option>
397
<option value="21">21</option>
398
<option value="22">22</option>
399
<option value="23">23</option>
400
<option value="24">24</option>
401
<option value="25">25</option>
402
<option value="26">26</option>
403
<option value="27">27</option>
404
<option value="28">28</option>
405
<option value="29">29</option>
406
<option value="30">30</option>
407
<option value="31">31</option>
409
<select name="date_month" id="id_date_month">
410
<option value="0">---</option>
411
<option value="1">januari</option>
412
<option value="2">februari</option>
413
<option value="3">maart</option>
414
<option value="4">april</option>
415
<option value="5">mei</option>
416
<option value="6">juni</option>
417
<option value="7">juli</option>
418
<option value="8" selected="selected">augustus</option>
419
<option value="9">september</option>
420
<option value="10">oktober</option>
421
<option value="11">november</option>
422
<option value="12">december</option>
424
<select name="date_year" id="id_date_year">
425
<option value="0">---</option>
426
<option value="2007">2007</option>
427
<option value="2008">2008</option>
428
<option value="2009">2009</option>
429
<option value="2010" selected="selected">2010</option>
430
<option value="2011">2011</option>
431
<option value="2012">2012</option>
432
<option value="2013">2013</option>
433
<option value="2014">2014</option>
434
<option value="2015">2015</option>
435
<option value="2016">2016</option>
438
Years before 1900 work
439
>>> w = SelectDateWidget(years=('1899',))
440
>>> w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date')
443
>>> translation.deactivate()
445
# MultiWidget and MultiValueField #############################################
446
# MultiWidgets are widgets composed of other widgets. They are usually
447
# combined with MultiValueFields - a field that is composed of other fields.
448
# MulitWidgets can themselved be composed of other MultiWidgets.
449
# SplitDateTimeWidget is one example of a MultiWidget.
451
>>> class ComplexMultiWidget(MultiWidget):
452
... def __init__(self, attrs=None):
455
... SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
456
... SplitDateTimeWidget(),
458
... super(ComplexMultiWidget, self).__init__(widgets, attrs)
460
... def decompress(self, value):
462
... data = value.split(',')
463
... return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])]
464
... return [None, None, None]
465
... def format_output(self, rendered_widgets):
466
... return u'\n'.join(rendered_widgets)
467
>>> w = ComplexMultiWidget()
468
>>> print w.render('name', 'some text,JP,2007-04-25 06:24:00')
469
<input type="text" name="name_0" value="some text" />
470
<select multiple="multiple" name="name_1">
471
<option value="J" selected="selected">John</option>
472
<option value="P" selected="selected">Paul</option>
473
<option value="G">George</option>
474
<option value="R">Ringo</option>
476
<input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />
478
>>> class ComplexField(MultiValueField):
479
... def __init__(self, required=True, widget=None, label=None, initial=None):
482
... MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
483
... SplitDateTimeField()
485
... super(ComplexField, self).__init__(fields, required, widget, label, initial)
487
... def compress(self, data_list):
489
... return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
492
>>> f = ComplexField(widget=w)
493
>>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']])
494
u'some text,JP,2007-04-25 06:24:00'
495
>>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']])
496
Traceback (most recent call last):
498
ValidationError: [u'Select a valid choice. X is not one of the available choices.']
500
# If insufficient data is provided, None is substituted
501
>>> f.clean(['some text',['JP']])
502
Traceback (most recent call last):
504
ValidationError: [u'This field is required.']
506
>>> class ComplexFieldForm(Form):
507
... field1 = ComplexField(widget=w)
508
>>> f = ComplexFieldForm()
510
<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
511
<select multiple="multiple" name="field1_1" id="id_field1_1">
512
<option value="J">John</option>
513
<option value="P">Paul</option>
514
<option value="G">George</option>
515
<option value="R">Ringo</option>
517
<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>
519
>>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
521
<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
522
<select multiple="multiple" name="field1_1" id="id_field1_1">
523
<option value="J" selected="selected">John</option>
524
<option value="P" selected="selected">Paul</option>
525
<option value="G">George</option>
526
<option value="R">Ringo</option>
528
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
530
>>> f.cleaned_data['field1']
531
u'some text,JP,2007-04-25 06:24:00'
534
# IPAddressField ##################################################################
536
>>> f = IPAddressField()
538
Traceback (most recent call last):
540
ValidationError: [u'This field is required.']
542
Traceback (most recent call last):
544
ValidationError: [u'This field is required.']
545
>>> f.clean('127.0.0.1')
548
Traceback (most recent call last):
550
ValidationError: [u'Enter a valid IPv4 address.']
551
>>> f.clean('127.0.0.')
552
Traceback (most recent call last):
554
ValidationError: [u'Enter a valid IPv4 address.']
555
>>> f.clean('1.2.3.4.5')
556
Traceback (most recent call last):
558
ValidationError: [u'Enter a valid IPv4 address.']
559
>>> f.clean('256.125.1.5')
560
Traceback (most recent call last):
562
ValidationError: [u'Enter a valid IPv4 address.']
564
>>> f = IPAddressField(required=False)
569
>>> f.clean('127.0.0.1')
572
Traceback (most recent call last):
574
ValidationError: [u'Enter a valid IPv4 address.']
575
>>> f.clean('127.0.0.')
576
Traceback (most recent call last):
578
ValidationError: [u'Enter a valid IPv4 address.']
579
>>> f.clean('1.2.3.4.5')
580
Traceback (most recent call last):
582
ValidationError: [u'Enter a valid IPv4 address.']
583
>>> f.clean('256.125.1.5')
584
Traceback (most recent call last):
586
ValidationError: [u'Enter a valid IPv4 address.']
588
#################################
589
# Tests of underlying functions #
590
#################################
592
# smart_unicode tests
593
>>> from django.utils.encoding import smart_unicode
595
... def __str__(self):
596
... return 'ŠĐĆŽćžšđ'
598
... def __str__(self):
600
... def __unicode__(self):
601
... return u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
602
>>> smart_unicode(Test())
603
u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
604
>>> smart_unicode(TestU())
605
u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
608
>>> smart_unicode('foo')
612
####################################
613
# Test accessing errors in clean() #
614
####################################
616
>>> class UserForm(Form):
617
... username = CharField(max_length=10)
618
... password = CharField(widget=PasswordInput)
620
... data = self.cleaned_data
621
... if not self.errors:
622
... data['username'] = data['username'].lower()
625
>>> f = UserForm({'username': 'SirRobin', 'password': 'blue'})
628
>>> f.cleaned_data['username']
631
#######################################
632
# Test overriding ErrorList in a form #
633
#######################################
635
>>> from django.forms.util import ErrorList
636
>>> class DivErrorList(ErrorList):
637
... def __unicode__(self):
638
... return self.as_divs()
639
... def as_divs(self):
640
... if not self: return u''
641
... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % force_unicode(e) for e in self])
642
>>> class CommentForm(Form):
643
... name = CharField(max_length=50, required=False)
644
... email = EmailField()
645
... comment = CharField()
646
>>> data = dict(email='invalid')
647
>>> f = CommentForm(data, auto_id=False, error_class=DivErrorList)
649
<p>Name: <input type="text" name="name" maxlength="50" /></p>
650
<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
651
<p>Email: <input type="text" name="email" value="invalid" /></p>
652
<div class="errorlist"><div class="error">This field is required.</div></div>
653
<p>Comment: <input type="text" name="comment" /></p>
655
#################################
656
# Test multipart-encoded form #
657
#################################
659
>>> class FormWithoutFile(Form):
660
... username = CharField()
661
>>> class FormWithFile(Form):
662
... username = CharField()
663
... file = FileField()
664
>>> class FormWithImage(Form):
665
... image = ImageField()
667
>>> FormWithoutFile().is_multipart()
669
>>> FormWithFile().is_multipart()
671
>>> FormWithImage().is_multipart()