Django

Code

root/django/trunk/tests/regressiontests/forms/extra.py

Revision 7971, 15.1 kB (checked in by jacob, 1 month ago)

Fixed #7741: django.newforms is now django.forms. This is obviously a backwards-incompatible change. There's a warning upon import of django.newforms itself, but deeper imports will raise errors.

  • Property svn:eol-style set to native
Line 
1 # -*- coding: utf-8 -*-
2 tests = r"""
3 >>> from django.forms import *
4 >>> from django.utils.encoding import force_unicode
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 # Extra stuff #
15 ###############
16
17 The forms library comes with some extra, higher-level Field and Widget
18 classes that demonstrate some of the library's abilities.
19
20 # SelectDateWidget ############################################################
21
22 >>> from django.forms.extras import SelectDateWidget
23 >>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
24 >>> print w.render('mydate', '')
25 <select name="mydate_month" id="id_mydate_month">
26 <option value="1">January</option>
27 <option value="2">February</option>
28 <option value="3">March</option>
29 <option value="4">April</option>
30 <option value="5">May</option>
31 <option value="6">June</option>
32 <option value="7">July</option>
33 <option value="8">August</option>
34 <option value="9">September</option>
35 <option value="10">October</option>
36 <option value="11">November</option>
37 <option value="12">December</option>
38 </select>
39 <select name="mydate_day" id="id_mydate_day">
40 <option value="1">1</option>
41 <option value="2">2</option>
42 <option value="3">3</option>
43 <option value="4">4</option>
44 <option value="5">5</option>
45 <option value="6">6</option>
46 <option value="7">7</option>
47 <option value="8">8</option>
48 <option value="9">9</option>
49 <option value="10">10</option>
50 <option value="11">11</option>
51 <option value="12">12</option>
52 <option value="13">13</option>
53 <option value="14">14</option>
54 <option value="15">15</option>
55 <option value="16">16</option>
56 <option value="17">17</option>
57 <option value="18">18</option>
58 <option value="19">19</option>
59 <option value="20">20</option>
60 <option value="21">21</option>
61 <option value="22">22</option>
62 <option value="23">23</option>
63 <option value="24">24</option>
64 <option value="25">25</option>
65 <option value="26">26</option>
66 <option value="27">27</option>
67 <option value="28">28</option>
68 <option value="29">29</option>
69 <option value="30">30</option>
70 <option value="31">31</option>
71 </select>
72 <select name="mydate_year" id="id_mydate_year">
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>
83 </select>
84 >>> w.render('mydate', None) == w.render('mydate', '')
85 True
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>
100 </select>
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>
133 </select>
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>
145 </select>
146
147 Accepts a datetime or a string:
148
149 >>> w.render('mydate', datetime.date(2010, 4, 15)) == w.render('mydate', '2010-04-15')
150 True
151
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>
167 </select>
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>
200 </select>
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>
212 </select>
213
214 Using a SelectDateWidget in a form:
215
216 >>> class GetDate(Form):
217 ...     mydate = DateField(widget=SelectDateWidget)
218 >>> a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'})
219 >>> print a.is_valid()
220 True
221 >>> print a.cleaned_data['mydate']
222 2008-04-01
223
224 As with any widget that implements get_value_from_datadict,
225 we must be prepared to accept the input from the "as_hidden"
226 rendering as well.
227
228 >>> print a['mydate'].as_hidden()
229 <input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />
230 >>> b=GetDate({'mydate':'2008-4-1'})
231 >>> print b.is_valid()
232 True
233 >>> print b.cleaned_data['mydate']
234 2008-04-01
235
236
237 # MultiWidget and MultiValueField #############################################
238 # MultiWidgets are widgets composed of other widgets. They are usually
239 # combined with MultiValueFields - a field that is composed of other fields.
240 # MulitWidgets can themselved be composed of other MultiWidgets.
241 # SplitDateTimeWidget is one example of a MultiWidget.
242
243 >>> class ComplexMultiWidget(MultiWidget):
244 ...     def __init__(self, attrs=None):
245 ...         widgets = (
246 ...             TextInput(),
247 ...             SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
248 ...             SplitDateTimeWidget(),
249 ...         )
250 ...         super(ComplexMultiWidget, self).__init__(widgets, attrs)
251 ...
252 ...     def decompress(self, value):
253 ...         if value:
254 ...             data = value.split(',')
255 ... return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])]
256 ...         return [None, None, None]
257 ...     def format_output(self, rendered_widgets):
258 ...         return u'\n'.join(rendered_widgets)
259 >>> w = ComplexMultiWidget()
260 >>> print w.render('name', 'some text,JP,2007-04-25 06:24:00')
261 <input type="text" name="name_0" value="some text" />
262 <select multiple="multiple" name="name_1">
263 <option value="J" selected="selected">John</option>
264 <option value="P" selected="selected">Paul</option>
265 <option value="G">George</option>
266 <option value="R">Ringo</option>
267 </select>
268 <input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />
269
270 >>> class ComplexField(MultiValueField):
271 ...     def __init__(self, required=True, widget=None, label=None, initial=None):
272 ...         fields = (
273 ...             CharField(),
274 ...             MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
275 ...             SplitDateTimeField()
276 ...         )
277 ...         super(ComplexField, self).__init__(fields, required, widget, label, initial)
278 ...
279 ...     def compress(self, data_list):
280 ...         if data_list:
281 ...             return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
282 ...         return None
283
284 >>> f = ComplexField(widget=w)
285 >>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']])
286 u'some text,JP,2007-04-25 06:24:00'
287 >>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']])
288 Traceback (most recent call last):
289 ...
290 ValidationError: [u'Select a valid choice. X is not one of the available choices.']
291
292 # If insufficient data is provided, None is substituted
293 >>> f.clean(['some text',['JP']])
294 Traceback (most recent call last):
295 ...
296 ValidationError: [u'This field is required.']
297
298 >>> class ComplexFieldForm(Form):
299 ...     field1 = ComplexField(widget=w)
300 >>> f = ComplexFieldForm()
301 >>> print f
302 <tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
303 <select multiple="multiple" name="field1_1" id="id_field1_1">
304 <option value="J">John</option>
305 <option value="P">Paul</option>
306 <option value="G">George</option>
307 <option value="R">Ringo</option>
308 </select>
309 <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>
310
311 >>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
312 >>> print f
313 <tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
314 <select multiple="multiple" name="field1_1" id="id_field1_1">
315 <option value="J" selected="selected">John</option>
316 <option value="P" selected="selected">Paul</option>
317 <option value="G">George</option>
318 <option value="R">Ringo</option>
319 </select>
320 <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>
321
322 >>> f.cleaned_data['field1']
323 u'some text,JP,2007-04-25 06:24:00'
324
325
326 # IPAddressField ##################################################################
327
328 >>> f = IPAddressField()
329 >>> f.clean('')
330 Traceback (most recent call last):
331 ...
332 ValidationError: [u'This field is required.']
333 >>> f.clean(None)
334 Traceback (most recent call last):
335 ...
336 ValidationError: [u'This field is required.']
337 >>> f.clean('127.0.0.1')
338 u'127.0.0.1'
339 >>> f.clean('foo')
340 Traceback (most recent call last):
341 ...
342 ValidationError: [u'Enter a valid IPv4 address.']
343 >>> f.clean('127.0.0.')
344 Traceback (most recent call last):
345 ...
346 ValidationError: [u'Enter a valid IPv4 address.']
347 >>> f.clean('1.2.3.4.5')
348 Traceback (most recent call last):
349 ...
350 ValidationError: [u'Enter a valid IPv4 address.']
351 >>> f.clean('256.125.1.5')
352 Traceback (most recent call last):
353 ...
354 ValidationError: [u'Enter a valid IPv4 address.']
355
356 >>> f = IPAddressField(required=False)
357 >>> f.clean('')
358 u''
359 >>> f.clean(None)
360 u''
361 >>> f.clean('127.0.0.1')
362 u'127.0.0.1'
363 >>> f.clean('foo')
364 Traceback (most recent call last):
365 ...
366 ValidationError: [u'Enter a valid IPv4 address.']
367 >>> f.clean('127.0.0.')
368 Traceback (most recent call last):
369 ...
370 ValidationError: [u'Enter a valid IPv4 address.']
371 >>> f.clean('1.2.3.4.5')
372 Traceback (most recent call last):
373 ...
374 ValidationError: [u'Enter a valid IPv4 address.']
375 >>> f.clean('256.125.1.5')
376 Traceback (most recent call last):
377 ...
378 ValidationError: [u'Enter a valid IPv4 address.']
379
380 #################################
381 # Tests of underlying functions #
382 #################################
383
384 # smart_unicode tests
385 >>> from django.utils.encoding import smart_unicode
386 >>> class Test:
387 ...     def __str__(self):
388 ...        return 'ŠĐĆŜćşšđ'
389 >>> class TestU:
390 ...     def __str__(self):
391 ...        return 'Foo'
392 ...     def __unicode__(self):
393 ...        return u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
394 >>> smart_unicode(Test())
395 u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
396 >>> smart_unicode(TestU())
397 u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
398 >>> smart_unicode(1)
399 u'1'
400 >>> smart_unicode('foo')
401 u'foo'
402
403
404 ####################################
405 # Test accessing errors in clean() #
406 ####################################
407
408 >>> class UserForm(Form):
409 ...     username = CharField(max_length=10)
410 ...     password = CharField(widget=PasswordInput)
411 ...     def clean(self):
412 ...         data = self.cleaned_data
413 ...         if not self.errors:
414 ...             data['username'] = data['username'].lower()
415 ...         return data
416
417 >>> f = UserForm({'username': 'SirRobin', 'password': 'blue'})
418 >>> f.is_valid()
419 True
420 >>> f.cleaned_data['username']
421 u'sirrobin'
422
423 #######################################
424 # Test overriding ErrorList in a form #
425 #######################################
426
427 >>> from django.forms.util import ErrorList
428 >>> class DivErrorList(ErrorList):
429 ...     def __unicode__(self):
430 ...         return self.as_divs()
431 ...     def as_divs(self):
432 ...         if not self: return u''
433 ...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % force_unicode(e) for e in self])
434 >>> class CommentForm(Form):
435 ...     name = CharField(max_length=50, required=False)
436 ...     email = EmailField()
437 ...     comment = CharField()
438 >>> data = dict(email='invalid')
439 >>> f = CommentForm(data, auto_id=False, error_class=DivErrorList)
440 >>> print f.as_p()
441 <p>Name: <input type="text" name="name" maxlength="50" /></p>
442 <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
443 <p>Email: <input type="text" name="email" value="invalid" /></p>
444 <div class="errorlist"><div class="error">This field is required.</div></div>
445 <p>Comment: <input type="text" name="comment" /></p>
446
447 #################################
448 # Test multipart-encoded form #
449 #################################
450
451 >>> class FormWithoutFile(Form):
452 ...     username = CharField()
453 >>> class FormWithFile(Form):
454 ...     username = CharField()
455 ...     file = FileField()
456 >>> class FormWithImage(Form):
457 ...     image = ImageField()
458
459 >>> FormWithoutFile().is_multipart()
460 False
461 >>> FormWithFile().is_multipart()
462 True
463 >>> FormWithImage().is_multipart()
464 True
465
466 """
Note: See TracBrowser for help on using the browser.