thirdparty/google_appengine/lib/django/tests/regressiontests/forms/tests.py
changeset 2866 a04b1e4126c4
parent 2864 2e0b0af889be
child 2868 9f7f269383f7
equal deleted inserted replaced
2864:2e0b0af889be 2866:a04b1e4126c4
     1 # -*- coding: utf-8 -*-
       
     2 r"""
       
     3 >>> from django.newforms import *
       
     4 >>> import datetime
       
     5 >>> import re
       
     6 
       
     7 ###########
       
     8 # Widgets #
       
     9 ###########
       
    10 
       
    11 Each Widget class corresponds to an HTML form widget. A Widget knows how to
       
    12 render itself, given a field name and some data. Widgets don't perform
       
    13 validation.
       
    14 
       
    15 # TextInput Widget ############################################################
       
    16 
       
    17 >>> w = TextInput()
       
    18 >>> w.render('email', '')
       
    19 u'<input type="text" name="email" />'
       
    20 >>> w.render('email', None)
       
    21 u'<input type="text" name="email" />'
       
    22 >>> w.render('email', 'test@example.com')
       
    23 u'<input type="text" name="email" value="test@example.com" />'
       
    24 >>> w.render('email', 'some "quoted" & ampersanded value')
       
    25 u'<input type="text" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
       
    26 >>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
       
    27 u'<input type="text" name="email" value="test@example.com" class="fun" />'
       
    28 
       
    29 # Note that doctest in Python 2.4 (and maybe 2.5?) doesn't support non-ascii
       
    30 # characters in output, so we're displaying the repr() here.
       
    31 >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
       
    32 u'<input type="text" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" class="fun" />'
       
    33 
       
    34 You can also pass 'attrs' to the constructor:
       
    35 >>> w = TextInput(attrs={'class': 'fun'})
       
    36 >>> w.render('email', '')
       
    37 u'<input type="text" class="fun" name="email" />'
       
    38 >>> w.render('email', 'foo@example.com')
       
    39 u'<input type="text" class="fun" value="foo@example.com" name="email" />'
       
    40 
       
    41 'attrs' passed to render() get precedence over those passed to the constructor:
       
    42 >>> w = TextInput(attrs={'class': 'pretty'})
       
    43 >>> w.render('email', '', attrs={'class': 'special'})
       
    44 u'<input type="text" class="special" name="email" />'
       
    45 
       
    46 # PasswordInput Widget ############################################################
       
    47 
       
    48 >>> w = PasswordInput()
       
    49 >>> w.render('email', '')
       
    50 u'<input type="password" name="email" />'
       
    51 >>> w.render('email', None)
       
    52 u'<input type="password" name="email" />'
       
    53 >>> w.render('email', 'test@example.com')
       
    54 u'<input type="password" name="email" value="test@example.com" />'
       
    55 >>> w.render('email', 'some "quoted" & ampersanded value')
       
    56 u'<input type="password" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
       
    57 >>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
       
    58 u'<input type="password" name="email" value="test@example.com" class="fun" />'
       
    59 
       
    60 You can also pass 'attrs' to the constructor:
       
    61 >>> w = PasswordInput(attrs={'class': 'fun'})
       
    62 >>> w.render('email', '')
       
    63 u'<input type="password" class="fun" name="email" />'
       
    64 >>> w.render('email', 'foo@example.com')
       
    65 u'<input type="password" class="fun" value="foo@example.com" name="email" />'
       
    66 
       
    67 'attrs' passed to render() get precedence over those passed to the constructor:
       
    68 >>> w = PasswordInput(attrs={'class': 'pretty'})
       
    69 >>> w.render('email', '', attrs={'class': 'special'})
       
    70 u'<input type="password" class="special" name="email" />'
       
    71 
       
    72 >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
       
    73 u'<input type="password" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
       
    74 
       
    75 The render_value argument lets you specify whether the widget should render
       
    76 its value. You may want to do this for security reasons.
       
    77 >>> w = PasswordInput(render_value=True)
       
    78 >>> w.render('email', 'secret')
       
    79 u'<input type="password" name="email" value="secret" />'
       
    80 >>> w = PasswordInput(render_value=False)
       
    81 >>> w.render('email', '')
       
    82 u'<input type="password" name="email" />'
       
    83 >>> w.render('email', None)
       
    84 u'<input type="password" name="email" />'
       
    85 >>> w.render('email', 'secret')
       
    86 u'<input type="password" name="email" />'
       
    87 >>> w = PasswordInput(attrs={'class': 'fun'}, render_value=False)
       
    88 >>> w.render('email', 'secret')
       
    89 u'<input type="password" class="fun" name="email" />'
       
    90 
       
    91 # HiddenInput Widget ############################################################
       
    92 
       
    93 >>> w = HiddenInput()
       
    94 >>> w.render('email', '')
       
    95 u'<input type="hidden" name="email" />'
       
    96 >>> w.render('email', None)
       
    97 u'<input type="hidden" name="email" />'
       
    98 >>> w.render('email', 'test@example.com')
       
    99 u'<input type="hidden" name="email" value="test@example.com" />'
       
   100 >>> w.render('email', 'some "quoted" & ampersanded value')
       
   101 u'<input type="hidden" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
       
   102 >>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
       
   103 u'<input type="hidden" name="email" value="test@example.com" class="fun" />'
       
   104 
       
   105 You can also pass 'attrs' to the constructor:
       
   106 >>> w = HiddenInput(attrs={'class': 'fun'})
       
   107 >>> w.render('email', '')
       
   108 u'<input type="hidden" class="fun" name="email" />'
       
   109 >>> w.render('email', 'foo@example.com')
       
   110 u'<input type="hidden" class="fun" value="foo@example.com" name="email" />'
       
   111 
       
   112 'attrs' passed to render() get precedence over those passed to the constructor:
       
   113 >>> w = HiddenInput(attrs={'class': 'pretty'})
       
   114 >>> w.render('email', '', attrs={'class': 'special'})
       
   115 u'<input type="hidden" class="special" name="email" />'
       
   116 
       
   117 >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
       
   118 u'<input type="hidden" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
       
   119 
       
   120 'attrs' passed to render() get precedence over those passed to the constructor:
       
   121 >>> w = HiddenInput(attrs={'class': 'pretty'})
       
   122 >>> w.render('email', '', attrs={'class': 'special'})
       
   123 u'<input type="hidden" class="special" name="email" />'
       
   124 
       
   125 # MultipleHiddenInput Widget ##################################################
       
   126 
       
   127 >>> w = MultipleHiddenInput()
       
   128 >>> w.render('email', [])
       
   129 u''
       
   130 >>> w.render('email', None)
       
   131 u''
       
   132 >>> w.render('email', ['test@example.com'])
       
   133 u'<input type="hidden" name="email" value="test@example.com" />'
       
   134 >>> w.render('email', ['some "quoted" & ampersanded value'])
       
   135 u'<input type="hidden" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
       
   136 >>> w.render('email', ['test@example.com', 'foo@example.com'])
       
   137 u'<input type="hidden" name="email" value="test@example.com" />\n<input type="hidden" name="email" value="foo@example.com" />'
       
   138 >>> w.render('email', ['test@example.com'], attrs={'class': 'fun'})
       
   139 u'<input type="hidden" name="email" value="test@example.com" class="fun" />'
       
   140 >>> w.render('email', ['test@example.com', 'foo@example.com'], attrs={'class': 'fun'})
       
   141 u'<input type="hidden" name="email" value="test@example.com" class="fun" />\n<input type="hidden" name="email" value="foo@example.com" class="fun" />'
       
   142 
       
   143 You can also pass 'attrs' to the constructor:
       
   144 >>> w = MultipleHiddenInput(attrs={'class': 'fun'})
       
   145 >>> w.render('email', [])
       
   146 u''
       
   147 >>> w.render('email', ['foo@example.com'])
       
   148 u'<input type="hidden" class="fun" value="foo@example.com" name="email" />'
       
   149 >>> w.render('email', ['foo@example.com', 'test@example.com'])
       
   150 u'<input type="hidden" class="fun" value="foo@example.com" name="email" />\n<input type="hidden" class="fun" value="test@example.com" name="email" />'
       
   151 
       
   152 'attrs' passed to render() get precedence over those passed to the constructor:
       
   153 >>> w = MultipleHiddenInput(attrs={'class': 'pretty'})
       
   154 >>> w.render('email', ['foo@example.com'], attrs={'class': 'special'})
       
   155 u'<input type="hidden" class="special" value="foo@example.com" name="email" />'
       
   156 
       
   157 >>> w.render('email', ['ŠĐĆŽćžšđ'], attrs={'class': 'fun'})
       
   158 u'<input type="hidden" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
       
   159 
       
   160 'attrs' passed to render() get precedence over those passed to the constructor:
       
   161 >>> w = MultipleHiddenInput(attrs={'class': 'pretty'})
       
   162 >>> w.render('email', ['foo@example.com'], attrs={'class': 'special'})
       
   163 u'<input type="hidden" class="special" value="foo@example.com" name="email" />'
       
   164 
       
   165 # FileInput Widget ############################################################
       
   166 
       
   167 >>> w = FileInput()
       
   168 >>> w.render('email', '')
       
   169 u'<input type="file" name="email" />'
       
   170 >>> w.render('email', None)
       
   171 u'<input type="file" name="email" />'
       
   172 >>> w.render('email', 'test@example.com')
       
   173 u'<input type="file" name="email" value="test@example.com" />'
       
   174 >>> w.render('email', 'some "quoted" & ampersanded value')
       
   175 u'<input type="file" name="email" value="some &quot;quoted&quot; &amp; ampersanded value" />'
       
   176 >>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
       
   177 u'<input type="file" name="email" value="test@example.com" class="fun" />'
       
   178 
       
   179 You can also pass 'attrs' to the constructor:
       
   180 >>> w = FileInput(attrs={'class': 'fun'})
       
   181 >>> w.render('email', '')
       
   182 u'<input type="file" class="fun" name="email" />'
       
   183 >>> w.render('email', 'foo@example.com')
       
   184 u'<input type="file" class="fun" value="foo@example.com" name="email" />'
       
   185 
       
   186 >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
       
   187 u'<input type="file" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
       
   188 
       
   189 # Textarea Widget #############################################################
       
   190 
       
   191 >>> w = Textarea()
       
   192 >>> w.render('msg', '')
       
   193 u'<textarea name="msg"></textarea>'
       
   194 >>> w.render('msg', None)
       
   195 u'<textarea name="msg"></textarea>'
       
   196 >>> w.render('msg', 'value')
       
   197 u'<textarea name="msg">value</textarea>'
       
   198 >>> w.render('msg', 'some "quoted" & ampersanded value')
       
   199 u'<textarea name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
       
   200 >>> w.render('msg', 'value', attrs={'class': 'pretty'})
       
   201 u'<textarea name="msg" class="pretty">value</textarea>'
       
   202 
       
   203 You can also pass 'attrs' to the constructor:
       
   204 >>> w = Textarea(attrs={'class': 'pretty'})
       
   205 >>> w.render('msg', '')
       
   206 u'<textarea class="pretty" name="msg"></textarea>'
       
   207 >>> w.render('msg', 'example')
       
   208 u'<textarea class="pretty" name="msg">example</textarea>'
       
   209 
       
   210 'attrs' passed to render() get precedence over those passed to the constructor:
       
   211 >>> w = Textarea(attrs={'class': 'pretty'})
       
   212 >>> w.render('msg', '', attrs={'class': 'special'})
       
   213 u'<textarea class="special" name="msg"></textarea>'
       
   214 
       
   215 >>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
       
   216 u'<textarea class="fun" name="msg">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>'
       
   217 
       
   218 # CheckboxInput Widget ########################################################
       
   219 
       
   220 >>> w = CheckboxInput()
       
   221 >>> w.render('is_cool', '')
       
   222 u'<input type="checkbox" name="is_cool" />'
       
   223 >>> w.render('is_cool', None)
       
   224 u'<input type="checkbox" name="is_cool" />'
       
   225 >>> w.render('is_cool', False)
       
   226 u'<input type="checkbox" name="is_cool" />'
       
   227 >>> w.render('is_cool', True)
       
   228 u'<input checked="checked" type="checkbox" name="is_cool" />'
       
   229 
       
   230 Using any value that's not in ('', None, False, True) will check the checkbox
       
   231 and set the 'value' attribute.
       
   232 >>> w.render('is_cool', 'foo')
       
   233 u'<input checked="checked" type="checkbox" name="is_cool" value="foo" />'
       
   234 
       
   235 >>> w.render('is_cool', False, attrs={'class': 'pretty'})
       
   236 u'<input type="checkbox" name="is_cool" class="pretty" />'
       
   237 
       
   238 You can also pass 'attrs' to the constructor:
       
   239 >>> w = CheckboxInput(attrs={'class': 'pretty'})
       
   240 >>> w.render('is_cool', '')
       
   241 u'<input type="checkbox" class="pretty" name="is_cool" />'
       
   242 
       
   243 'attrs' passed to render() get precedence over those passed to the constructor:
       
   244 >>> w = CheckboxInput(attrs={'class': 'pretty'})
       
   245 >>> w.render('is_cool', '', attrs={'class': 'special'})
       
   246 u'<input type="checkbox" class="special" name="is_cool" />'
       
   247 
       
   248 You can pass 'check_test' to the constructor. This is a callable that takes the
       
   249 value and returns True if the box should be checked.
       
   250 >>> w = CheckboxInput(check_test=lambda value: value.startswith('hello'))
       
   251 >>> w.render('greeting', '')
       
   252 u'<input type="checkbox" name="greeting" />'
       
   253 >>> w.render('greeting', 'hello')
       
   254 u'<input checked="checked" type="checkbox" name="greeting" value="hello" />'
       
   255 >>> w.render('greeting', 'hello there')
       
   256 u'<input checked="checked" type="checkbox" name="greeting" value="hello there" />'
       
   257 >>> w.render('greeting', 'hello & goodbye')
       
   258 u'<input checked="checked" type="checkbox" name="greeting" value="hello &amp; goodbye" />'
       
   259 
       
   260 A subtlety: If the 'check_test' argument cannot handle a value and raises any
       
   261 exception during its __call__, then the exception will be swallowed and the box
       
   262 will not be checked. In this example, the 'check_test' assumes the value has a
       
   263 startswith() method, which fails for the values True, False and None.
       
   264 >>> w.render('greeting', True)
       
   265 u'<input type="checkbox" name="greeting" />'
       
   266 >>> w.render('greeting', False)
       
   267 u'<input type="checkbox" name="greeting" />'
       
   268 >>> w.render('greeting', None)
       
   269 u'<input type="checkbox" name="greeting" />'
       
   270 
       
   271 # Select Widget ###############################################################
       
   272 
       
   273 >>> w = Select()
       
   274 >>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   275 <select name="beatle">
       
   276 <option value="J" selected="selected">John</option>
       
   277 <option value="P">Paul</option>
       
   278 <option value="G">George</option>
       
   279 <option value="R">Ringo</option>
       
   280 </select>
       
   281 
       
   282 If the value is None, none of the options are selected:
       
   283 >>> print w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   284 <select name="beatle">
       
   285 <option value="J">John</option>
       
   286 <option value="P">Paul</option>
       
   287 <option value="G">George</option>
       
   288 <option value="R">Ringo</option>
       
   289 </select>
       
   290 
       
   291 If the value corresponds to a label (but not to an option value), none of the options are selected:
       
   292 >>> print w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   293 <select name="beatle">
       
   294 <option value="J">John</option>
       
   295 <option value="P">Paul</option>
       
   296 <option value="G">George</option>
       
   297 <option value="R">Ringo</option>
       
   298 </select>
       
   299 
       
   300 The value is compared to its str():
       
   301 >>> print w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')])
       
   302 <select name="num">
       
   303 <option value="1">1</option>
       
   304 <option value="2" selected="selected">2</option>
       
   305 <option value="3">3</option>
       
   306 </select>
       
   307 >>> print w.render('num', '2', choices=[(1, 1), (2, 2), (3, 3)])
       
   308 <select name="num">
       
   309 <option value="1">1</option>
       
   310 <option value="2" selected="selected">2</option>
       
   311 <option value="3">3</option>
       
   312 </select>
       
   313 >>> print w.render('num', 2, choices=[(1, 1), (2, 2), (3, 3)])
       
   314 <select name="num">
       
   315 <option value="1">1</option>
       
   316 <option value="2" selected="selected">2</option>
       
   317 <option value="3">3</option>
       
   318 </select>
       
   319 
       
   320 The 'choices' argument can be any iterable:
       
   321 >>> from itertools import chain
       
   322 >>> def get_choices():
       
   323 ...     for i in range(5):
       
   324 ...         yield (i, i)
       
   325 >>> print w.render('num', 2, choices=get_choices())
       
   326 <select name="num">
       
   327 <option value="0">0</option>
       
   328 <option value="1">1</option>
       
   329 <option value="2" selected="selected">2</option>
       
   330 <option value="3">3</option>
       
   331 <option value="4">4</option>
       
   332 </select>
       
   333 >>> things = ({'id': 1, 'name': 'And Boom'}, {'id': 2, 'name': 'One More Thing!'})
       
   334 >>> class SomeForm(Form):
       
   335 ...     somechoice = ChoiceField(choices=chain((('', '-'*9),), [(thing['id'], thing['name']) for thing in things]))
       
   336 >>> f = SomeForm()
       
   337 >>> f.as_table()
       
   338 u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
       
   339 >>> f.as_table()
       
   340 u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
       
   341 >>> f = SomeForm({'somechoice': 2})
       
   342 >>> f.as_table()
       
   343 u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="">---------</option>\n<option value="1">And Boom</option>\n<option value="2" selected="selected">One More Thing!</option>\n</select></td></tr>'
       
   344 
       
   345 You can also pass 'choices' to the constructor:
       
   346 >>> w = Select(choices=[(1, 1), (2, 2), (3, 3)])
       
   347 >>> print w.render('num', 2)
       
   348 <select name="num">
       
   349 <option value="1">1</option>
       
   350 <option value="2" selected="selected">2</option>
       
   351 <option value="3">3</option>
       
   352 </select>
       
   353 
       
   354 If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
       
   355 >>> print w.render('num', 2, choices=[(4, 4), (5, 5)])
       
   356 <select name="num">
       
   357 <option value="1">1</option>
       
   358 <option value="2" selected="selected">2</option>
       
   359 <option value="3">3</option>
       
   360 <option value="4">4</option>
       
   361 <option value="5">5</option>
       
   362 </select>
       
   363 
       
   364 >>> w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
       
   365 u'<select name="email">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>'
       
   366 
       
   367 If choices is passed to the constructor and is a generator, it can be iterated
       
   368 over multiple times without getting consumed:
       
   369 >>> w = Select(choices=get_choices())
       
   370 >>> print w.render('num', 2)
       
   371 <select name="num">
       
   372 <option value="0">0</option>
       
   373 <option value="1">1</option>
       
   374 <option value="2" selected="selected">2</option>
       
   375 <option value="3">3</option>
       
   376 <option value="4">4</option>
       
   377 </select>
       
   378 >>> print w.render('num', 3)
       
   379 <select name="num">
       
   380 <option value="0">0</option>
       
   381 <option value="1">1</option>
       
   382 <option value="2">2</option>
       
   383 <option value="3" selected="selected">3</option>
       
   384 <option value="4">4</option>
       
   385 </select>
       
   386 
       
   387 # NullBooleanSelect Widget ####################################################
       
   388 
       
   389 >>> w = NullBooleanSelect()
       
   390 >>> print w.render('is_cool', True)
       
   391 <select name="is_cool">
       
   392 <option value="1">Unknown</option>
       
   393 <option value="2" selected="selected">Yes</option>
       
   394 <option value="3">No</option>
       
   395 </select>
       
   396 >>> print w.render('is_cool', False)
       
   397 <select name="is_cool">
       
   398 <option value="1">Unknown</option>
       
   399 <option value="2">Yes</option>
       
   400 <option value="3" selected="selected">No</option>
       
   401 </select>
       
   402 >>> print w.render('is_cool', None)
       
   403 <select name="is_cool">
       
   404 <option value="1" selected="selected">Unknown</option>
       
   405 <option value="2">Yes</option>
       
   406 <option value="3">No</option>
       
   407 </select>
       
   408 >>> print w.render('is_cool', '2')
       
   409 <select name="is_cool">
       
   410 <option value="1">Unknown</option>
       
   411 <option value="2" selected="selected">Yes</option>
       
   412 <option value="3">No</option>
       
   413 </select>
       
   414 >>> print w.render('is_cool', '3')
       
   415 <select name="is_cool">
       
   416 <option value="1">Unknown</option>
       
   417 <option value="2">Yes</option>
       
   418 <option value="3" selected="selected">No</option>
       
   419 </select>
       
   420 
       
   421 # SelectMultiple Widget #######################################################
       
   422 
       
   423 >>> w = SelectMultiple()
       
   424 >>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   425 <select multiple="multiple" name="beatles">
       
   426 <option value="J" selected="selected">John</option>
       
   427 <option value="P">Paul</option>
       
   428 <option value="G">George</option>
       
   429 <option value="R">Ringo</option>
       
   430 </select>
       
   431 >>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   432 <select multiple="multiple" name="beatles">
       
   433 <option value="J" selected="selected">John</option>
       
   434 <option value="P" selected="selected">Paul</option>
       
   435 <option value="G">George</option>
       
   436 <option value="R">Ringo</option>
       
   437 </select>
       
   438 >>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   439 <select multiple="multiple" name="beatles">
       
   440 <option value="J" selected="selected">John</option>
       
   441 <option value="P" selected="selected">Paul</option>
       
   442 <option value="G">George</option>
       
   443 <option value="R" selected="selected">Ringo</option>
       
   444 </select>
       
   445 
       
   446 If the value is None, none of the options are selected:
       
   447 >>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   448 <select multiple="multiple" name="beatles">
       
   449 <option value="J">John</option>
       
   450 <option value="P">Paul</option>
       
   451 <option value="G">George</option>
       
   452 <option value="R">Ringo</option>
       
   453 </select>
       
   454 
       
   455 If the value corresponds to a label (but not to an option value), none of the options are selected:
       
   456 >>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   457 <select multiple="multiple" name="beatles">
       
   458 <option value="J">John</option>
       
   459 <option value="P">Paul</option>
       
   460 <option value="G">George</option>
       
   461 <option value="R">Ringo</option>
       
   462 </select>
       
   463 
       
   464 If multiple values are given, but some of them are not valid, the valid ones are selected:
       
   465 >>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   466 <select multiple="multiple" name="beatles">
       
   467 <option value="J" selected="selected">John</option>
       
   468 <option value="P">Paul</option>
       
   469 <option value="G" selected="selected">George</option>
       
   470 <option value="R">Ringo</option>
       
   471 </select>
       
   472 
       
   473 The value is compared to its str():
       
   474 >>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
       
   475 <select multiple="multiple" name="nums">
       
   476 <option value="1">1</option>
       
   477 <option value="2" selected="selected">2</option>
       
   478 <option value="3">3</option>
       
   479 </select>
       
   480 >>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)])
       
   481 <select multiple="multiple" name="nums">
       
   482 <option value="1">1</option>
       
   483 <option value="2" selected="selected">2</option>
       
   484 <option value="3">3</option>
       
   485 </select>
       
   486 >>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)])
       
   487 <select multiple="multiple" name="nums">
       
   488 <option value="1">1</option>
       
   489 <option value="2" selected="selected">2</option>
       
   490 <option value="3">3</option>
       
   491 </select>
       
   492 
       
   493 The 'choices' argument can be any iterable:
       
   494 >>> def get_choices():
       
   495 ...     for i in range(5):
       
   496 ...         yield (i, i)
       
   497 >>> print w.render('nums', [2], choices=get_choices())
       
   498 <select multiple="multiple" name="nums">
       
   499 <option value="0">0</option>
       
   500 <option value="1">1</option>
       
   501 <option value="2" selected="selected">2</option>
       
   502 <option value="3">3</option>
       
   503 <option value="4">4</option>
       
   504 </select>
       
   505 
       
   506 You can also pass 'choices' to the constructor:
       
   507 >>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
       
   508 >>> print w.render('nums', [2])
       
   509 <select multiple="multiple" name="nums">
       
   510 <option value="1">1</option>
       
   511 <option value="2" selected="selected">2</option>
       
   512 <option value="3">3</option>
       
   513 </select>
       
   514 
       
   515 If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
       
   516 >>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
       
   517 <select multiple="multiple" name="nums">
       
   518 <option value="1">1</option>
       
   519 <option value="2" selected="selected">2</option>
       
   520 <option value="3">3</option>
       
   521 <option value="4">4</option>
       
   522 <option value="5">5</option>
       
   523 </select>
       
   524 
       
   525 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
       
   526 u'<select multiple="multiple" name="nums">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>'
       
   527 
       
   528 # RadioSelect Widget ##########################################################
       
   529 
       
   530 >>> w = RadioSelect()
       
   531 >>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   532 <ul>
       
   533 <li><label><input checked="checked" type="radio" name="beatle" value="J" /> John</label></li>
       
   534 <li><label><input type="radio" name="beatle" value="P" /> Paul</label></li>
       
   535 <li><label><input type="radio" name="beatle" value="G" /> George</label></li>
       
   536 <li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li>
       
   537 </ul>
       
   538 
       
   539 If the value is None, none of the options are checked:
       
   540 >>> print w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   541 <ul>
       
   542 <li><label><input type="radio" name="beatle" value="J" /> John</label></li>
       
   543 <li><label><input type="radio" name="beatle" value="P" /> Paul</label></li>
       
   544 <li><label><input type="radio" name="beatle" value="G" /> George</label></li>
       
   545 <li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li>
       
   546 </ul>
       
   547 
       
   548 If the value corresponds to a label (but not to an option value), none of the options are checked:
       
   549 >>> print w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   550 <ul>
       
   551 <li><label><input type="radio" name="beatle" value="J" /> John</label></li>
       
   552 <li><label><input type="radio" name="beatle" value="P" /> Paul</label></li>
       
   553 <li><label><input type="radio" name="beatle" value="G" /> George</label></li>
       
   554 <li><label><input type="radio" name="beatle" value="R" /> Ringo</label></li>
       
   555 </ul>
       
   556 
       
   557 The value is compared to its str():
       
   558 >>> print w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')])
       
   559 <ul>
       
   560 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   561 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   562 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   563 </ul>
       
   564 >>> print w.render('num', '2', choices=[(1, 1), (2, 2), (3, 3)])
       
   565 <ul>
       
   566 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   567 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   568 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   569 </ul>
       
   570 >>> print w.render('num', 2, choices=[(1, 1), (2, 2), (3, 3)])
       
   571 <ul>
       
   572 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   573 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   574 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   575 </ul>
       
   576 
       
   577 The 'choices' argument can be any iterable:
       
   578 >>> def get_choices():
       
   579 ...     for i in range(5):
       
   580 ...         yield (i, i)
       
   581 >>> print w.render('num', 2, choices=get_choices())
       
   582 <ul>
       
   583 <li><label><input type="radio" name="num" value="0" /> 0</label></li>
       
   584 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   585 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   586 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   587 <li><label><input type="radio" name="num" value="4" /> 4</label></li>
       
   588 </ul>
       
   589 
       
   590 You can also pass 'choices' to the constructor:
       
   591 >>> w = RadioSelect(choices=[(1, 1), (2, 2), (3, 3)])
       
   592 >>> print w.render('num', 2)
       
   593 <ul>
       
   594 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   595 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   596 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   597 </ul>
       
   598 
       
   599 If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
       
   600 >>> print w.render('num', 2, choices=[(4, 4), (5, 5)])
       
   601 <ul>
       
   602 <li><label><input type="radio" name="num" value="1" /> 1</label></li>
       
   603 <li><label><input checked="checked" type="radio" name="num" value="2" /> 2</label></li>
       
   604 <li><label><input type="radio" name="num" value="3" /> 3</label></li>
       
   605 <li><label><input type="radio" name="num" value="4" /> 4</label></li>
       
   606 <li><label><input type="radio" name="num" value="5" /> 5</label></li>
       
   607 </ul>
       
   608 
       
   609 The render() method returns a RadioFieldRenderer object, whose str() is a <ul>.
       
   610 You can manipulate that object directly to customize the way the RadioSelect
       
   611 is rendered.
       
   612 >>> w = RadioSelect()
       
   613 >>> r = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   614 >>> for inp in r:
       
   615 ...     print inp
       
   616 <label><input checked="checked" type="radio" name="beatle" value="J" /> John</label>
       
   617 <label><input type="radio" name="beatle" value="P" /> Paul</label>
       
   618 <label><input type="radio" name="beatle" value="G" /> George</label>
       
   619 <label><input type="radio" name="beatle" value="R" /> Ringo</label>
       
   620 >>> for inp in r:
       
   621 ...     print '%s<br />' % inp
       
   622 <label><input checked="checked" type="radio" name="beatle" value="J" /> John</label><br />
       
   623 <label><input type="radio" name="beatle" value="P" /> Paul</label><br />
       
   624 <label><input type="radio" name="beatle" value="G" /> George</label><br />
       
   625 <label><input type="radio" name="beatle" value="R" /> Ringo</label><br />
       
   626 >>> for inp in r:
       
   627 ...     print '<p>%s %s</p>' % (inp.tag(), inp.choice_label)
       
   628 <p><input checked="checked" type="radio" name="beatle" value="J" /> John</p>
       
   629 <p><input type="radio" name="beatle" value="P" /> Paul</p>
       
   630 <p><input type="radio" name="beatle" value="G" /> George</p>
       
   631 <p><input type="radio" name="beatle" value="R" /> Ringo</p>
       
   632 >>> for inp in r:
       
   633 ...     print '%s %s %s %s %s' % (inp.name, inp.value, inp.choice_value, inp.choice_label, inp.is_checked())
       
   634 beatle J J John True
       
   635 beatle J P Paul False
       
   636 beatle J G George False
       
   637 beatle J R Ringo False
       
   638 
       
   639 A RadioFieldRenderer object also allows index access to individual RadioInput
       
   640 objects.
       
   641 >>> w = RadioSelect()
       
   642 >>> r = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   643 >>> print r[1]
       
   644 <label><input type="radio" name="beatle" value="P" /> Paul</label>
       
   645 >>> print r[0]
       
   646 <label><input checked="checked" type="radio" name="beatle" value="J" /> John</label>
       
   647 >>> r[0].is_checked()
       
   648 True
       
   649 >>> r[1].is_checked()
       
   650 False
       
   651 >>> r[1].name, r[1].value, r[1].choice_value, r[1].choice_label
       
   652 ('beatle', u'J', u'P', u'Paul')
       
   653 >>> r[10]
       
   654 Traceback (most recent call last):
       
   655 ...
       
   656 IndexError: list index out of range
       
   657 
       
   658 >>> w = RadioSelect()
       
   659 >>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
       
   660 u'<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
       
   661 
       
   662 # CheckboxSelectMultiple Widget ###############################################
       
   663 
       
   664 >>> w = CheckboxSelectMultiple()
       
   665 >>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   666 <ul>
       
   667 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
       
   668 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   669 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
       
   670 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   671 </ul>
       
   672 >>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   673 <ul>
       
   674 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
       
   675 <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   676 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
       
   677 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   678 </ul>
       
   679 >>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   680 <ul>
       
   681 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
       
   682 <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   683 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
       
   684 <li><label><input checked="checked" type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   685 </ul>
       
   686 
       
   687 If the value is None, none of the options are selected:
       
   688 >>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   689 <ul>
       
   690 <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li>
       
   691 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   692 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
       
   693 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   694 </ul>
       
   695 
       
   696 If the value corresponds to a label (but not to an option value), none of the options are selected:
       
   697 >>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   698 <ul>
       
   699 <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li>
       
   700 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   701 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
       
   702 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   703 </ul>
       
   704 
       
   705 If multiple values are given, but some of them are not valid, the valid ones are selected:
       
   706 >>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
       
   707 <ul>
       
   708 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
       
   709 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
       
   710 <li><label><input checked="checked" type="checkbox" name="beatles" value="G" /> George</label></li>
       
   711 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
       
   712 </ul>
       
   713 
       
   714 The value is compared to its str():
       
   715 >>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
       
   716 <ul>
       
   717 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   718 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   719 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   720 </ul>
       
   721 >>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)])
       
   722 <ul>
       
   723 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   724 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   725 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   726 </ul>
       
   727 >>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)])
       
   728 <ul>
       
   729 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   730 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   731 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   732 </ul>
       
   733 
       
   734 The 'choices' argument can be any iterable:
       
   735 >>> def get_choices():
       
   736 ...     for i in range(5):
       
   737 ...         yield (i, i)
       
   738 >>> print w.render('nums', [2], choices=get_choices())
       
   739 <ul>
       
   740 <li><label><input type="checkbox" name="nums" value="0" /> 0</label></li>
       
   741 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   742 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   743 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   744 <li><label><input type="checkbox" name="nums" value="4" /> 4</label></li>
       
   745 </ul>
       
   746 
       
   747 You can also pass 'choices' to the constructor:
       
   748 >>> w = CheckboxSelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
       
   749 >>> print w.render('nums', [2])
       
   750 <ul>
       
   751 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   752 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   753 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   754 </ul>
       
   755 
       
   756 If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
       
   757 >>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
       
   758 <ul>
       
   759 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
       
   760 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
       
   761 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
       
   762 <li><label><input type="checkbox" name="nums" value="4" /> 4</label></li>
       
   763 <li><label><input type="checkbox" name="nums" value="5" /> 5</label></li>
       
   764 </ul>
       
   765 
       
   766 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
       
   767 u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
       
   768 
       
   769 # MultiWidget #################################################################
       
   770 
       
   771 >>> class MyMultiWidget(MultiWidget):
       
   772 ...     def decompress(self, value):
       
   773 ...         if value:
       
   774 ...             return value.split('__')
       
   775 ...         return ['', '']
       
   776 ...     def format_output(self, rendered_widgets):
       
   777 ...         return u'<br />'.join(rendered_widgets)
       
   778 >>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})))
       
   779 >>> w.render('name', ['john', 'lennon'])
       
   780 u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
       
   781 >>> w.render('name', 'john__lennon')
       
   782 u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
       
   783 
       
   784 # SplitDateTimeWidget #########################################################
       
   785 
       
   786 >>> w = SplitDateTimeWidget()
       
   787 >>> w.render('date', '')
       
   788 u'<input type="text" name="date_0" /><input type="text" name="date_1" />'
       
   789 >>> w.render('date', None)
       
   790 u'<input type="text" name="date_0" /><input type="text" name="date_1" />'
       
   791 >>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30))
       
   792 u'<input type="text" name="date_0" value="2006-01-10" /><input type="text" name="date_1" value="07:30:00" />'
       
   793 >>> w.render('date', [datetime.date(2006, 1, 10), datetime.time(7, 30)])
       
   794 u'<input type="text" name="date_0" value="2006-01-10" /><input type="text" name="date_1" value="07:30:00" />'
       
   795 
       
   796 You can also pass 'attrs' to the constructor. In this case, the attrs will be
       
   797 included on both widgets.
       
   798 >>> w = SplitDateTimeWidget(attrs={'class': 'pretty'})
       
   799 >>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30))
       
   800 u'<input type="text" class="pretty" value="2006-01-10" name="date_0" /><input type="text" class="pretty" value="07:30:00" name="date_1" />'
       
   801 
       
   802 ##########
       
   803 # Fields #
       
   804 ##########
       
   805 
       
   806 Each Field class does some sort of validation. Each Field has a clean() method,
       
   807 which either raises django.newforms.ValidationError or returns the "clean"
       
   808 data -- usually a Unicode object, but, in some rare cases, a list.
       
   809 
       
   810 Each Field's __init__() takes at least these parameters:
       
   811     required -- Boolean that specifies whether the field is required.
       
   812                 True by default.
       
   813     widget -- A Widget class, or instance of a Widget class, that should be
       
   814               used for this Field when displaying it. Each Field has a default
       
   815               Widget that it'll use if you don't specify this. In most cases,
       
   816               the default widget is TextInput.
       
   817     label -- A verbose name for this field, for use in displaying this field in
       
   818              a form. By default, Django will use a "pretty" version of the form
       
   819              field name, if the Field is part of a Form.
       
   820     initial -- A value to use in this Field's initial display. This value is
       
   821                *not* used as a fallback if data isn't given.
       
   822 
       
   823 Other than that, the Field subclasses have class-specific options for
       
   824 __init__(). For example, CharField has a max_length option.
       
   825 
       
   826 # CharField ###################################################################
       
   827 
       
   828 >>> f = CharField()
       
   829 >>> f.clean(1)
       
   830 u'1'
       
   831 >>> f.clean('hello')
       
   832 u'hello'
       
   833 >>> f.clean(None)
       
   834 Traceback (most recent call last):
       
   835 ...
       
   836 ValidationError: [u'This field is required.']
       
   837 >>> f.clean('')
       
   838 Traceback (most recent call last):
       
   839 ...
       
   840 ValidationError: [u'This field is required.']
       
   841 >>> f.clean([1, 2, 3])
       
   842 u'[1, 2, 3]'
       
   843 
       
   844 >>> f = CharField(required=False)
       
   845 >>> f.clean(1)
       
   846 u'1'
       
   847 >>> f.clean('hello')
       
   848 u'hello'
       
   849 >>> f.clean(None)
       
   850 u''
       
   851 >>> f.clean('')
       
   852 u''
       
   853 >>> f.clean([1, 2, 3])
       
   854 u'[1, 2, 3]'
       
   855 
       
   856 CharField accepts an optional max_length parameter:
       
   857 >>> f = CharField(max_length=10, required=False)
       
   858 >>> f.clean('12345')
       
   859 u'12345'
       
   860 >>> f.clean('1234567890')
       
   861 u'1234567890'
       
   862 >>> f.clean('1234567890a')
       
   863 Traceback (most recent call last):
       
   864 ...
       
   865 ValidationError: [u'Ensure this value has at most 10 characters.']
       
   866 
       
   867 CharField accepts an optional min_length parameter:
       
   868 >>> f = CharField(min_length=10, required=False)
       
   869 >>> f.clean('')
       
   870 u''
       
   871 >>> f.clean('12345')
       
   872 Traceback (most recent call last):
       
   873 ...
       
   874 ValidationError: [u'Ensure this value has at least 10 characters.']
       
   875 >>> f.clean('1234567890')
       
   876 u'1234567890'
       
   877 >>> f.clean('1234567890a')
       
   878 u'1234567890a'
       
   879 
       
   880 >>> f = CharField(min_length=10, required=True)
       
   881 >>> f.clean('')
       
   882 Traceback (most recent call last):
       
   883 ...
       
   884 ValidationError: [u'This field is required.']
       
   885 >>> f.clean('12345')
       
   886 Traceback (most recent call last):
       
   887 ...
       
   888 ValidationError: [u'Ensure this value has at least 10 characters.']
       
   889 >>> f.clean('1234567890')
       
   890 u'1234567890'
       
   891 >>> f.clean('1234567890a')
       
   892 u'1234567890a'
       
   893 
       
   894 # IntegerField ################################################################
       
   895 
       
   896 >>> f = IntegerField()
       
   897 >>> f.clean('')
       
   898 Traceback (most recent call last):
       
   899 ...
       
   900 ValidationError: [u'This field is required.']
       
   901 >>> f.clean(None)
       
   902 Traceback (most recent call last):
       
   903 ...
       
   904 ValidationError: [u'This field is required.']
       
   905 >>> f.clean('1')
       
   906 1
       
   907 >>> isinstance(f.clean('1'), int)
       
   908 True
       
   909 >>> f.clean('23')
       
   910 23
       
   911 >>> f.clean('a')
       
   912 Traceback (most recent call last):
       
   913 ...
       
   914 ValidationError: [u'Enter a whole number.']
       
   915 >>> f.clean('1 ')
       
   916 1
       
   917 >>> f.clean(' 1')
       
   918 1
       
   919 >>> f.clean(' 1 ')
       
   920 1
       
   921 >>> f.clean('1a')
       
   922 Traceback (most recent call last):
       
   923 ...
       
   924 ValidationError: [u'Enter a whole number.']
       
   925 
       
   926 >>> f = IntegerField(required=False)
       
   927 >>> f.clean('')
       
   928 >>> repr(f.clean(''))
       
   929 'None'
       
   930 >>> f.clean(None)
       
   931 >>> repr(f.clean(None))
       
   932 'None'
       
   933 >>> f.clean('1')
       
   934 1
       
   935 >>> isinstance(f.clean('1'), int)
       
   936 True
       
   937 >>> f.clean('23')
       
   938 23
       
   939 >>> f.clean('a')
       
   940 Traceback (most recent call last):
       
   941 ...
       
   942 ValidationError: [u'Enter a whole number.']
       
   943 >>> f.clean('1 ')
       
   944 1
       
   945 >>> f.clean(' 1')
       
   946 1
       
   947 >>> f.clean(' 1 ')
       
   948 1
       
   949 >>> f.clean('1a')
       
   950 Traceback (most recent call last):
       
   951 ...
       
   952 ValidationError: [u'Enter a whole number.']
       
   953 
       
   954 IntegerField accepts an optional max_value parameter:
       
   955 >>> f = IntegerField(max_value=10)
       
   956 >>> f.clean(None)
       
   957 Traceback (most recent call last):
       
   958 ...
       
   959 ValidationError: [u'This field is required.']
       
   960 >>> f.clean(1)
       
   961 1
       
   962 >>> f.clean(10)
       
   963 10
       
   964 >>> f.clean(11)
       
   965 Traceback (most recent call last):
       
   966 ...
       
   967 ValidationError: [u'Ensure this value is less than or equal to 10.']
       
   968 >>> f.clean('10')
       
   969 10
       
   970 >>> f.clean('11')
       
   971 Traceback (most recent call last):
       
   972 ...
       
   973 ValidationError: [u'Ensure this value is less than or equal to 10.']
       
   974 
       
   975 IntegerField accepts an optional min_value parameter:
       
   976 >>> f = IntegerField(min_value=10)
       
   977 >>> f.clean(None)
       
   978 Traceback (most recent call last):
       
   979 ...
       
   980 ValidationError: [u'This field is required.']
       
   981 >>> f.clean(1)
       
   982 Traceback (most recent call last):
       
   983 ...
       
   984 ValidationError: [u'Ensure this value is greater than or equal to 10.']
       
   985 >>> f.clean(10)
       
   986 10
       
   987 >>> f.clean(11)
       
   988 11
       
   989 >>> f.clean('10')
       
   990 10
       
   991 >>> f.clean('11')
       
   992 11
       
   993 
       
   994 min_value and max_value can be used together:
       
   995 >>> f = IntegerField(min_value=10, max_value=20)
       
   996 >>> f.clean(None)
       
   997 Traceback (most recent call last):
       
   998 ...
       
   999 ValidationError: [u'This field is required.']
       
  1000 >>> f.clean(1)
       
  1001 Traceback (most recent call last):
       
  1002 ...
       
  1003 ValidationError: [u'Ensure this value is greater than or equal to 10.']
       
  1004 >>> f.clean(10)
       
  1005 10
       
  1006 >>> f.clean(11)
       
  1007 11
       
  1008 >>> f.clean('10')
       
  1009 10
       
  1010 >>> f.clean('11')
       
  1011 11
       
  1012 >>> f.clean(20)
       
  1013 20
       
  1014 >>> f.clean(21)
       
  1015 Traceback (most recent call last):
       
  1016 ...
       
  1017 ValidationError: [u'Ensure this value is less than or equal to 20.']
       
  1018 
       
  1019 # DateField ###################################################################
       
  1020 
       
  1021 >>> import datetime
       
  1022 >>> f = DateField()
       
  1023 >>> f.clean(datetime.date(2006, 10, 25))
       
  1024 datetime.date(2006, 10, 25)
       
  1025 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
       
  1026 datetime.date(2006, 10, 25)
       
  1027 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
       
  1028 datetime.date(2006, 10, 25)
       
  1029 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
       
  1030 datetime.date(2006, 10, 25)
       
  1031 >>> f.clean('2006-10-25')
       
  1032 datetime.date(2006, 10, 25)
       
  1033 >>> f.clean('10/25/2006')
       
  1034 datetime.date(2006, 10, 25)
       
  1035 >>> f.clean('10/25/06')
       
  1036 datetime.date(2006, 10, 25)
       
  1037 >>> f.clean('Oct 25 2006')
       
  1038 datetime.date(2006, 10, 25)
       
  1039 >>> f.clean('October 25 2006')
       
  1040 datetime.date(2006, 10, 25)
       
  1041 >>> f.clean('October 25, 2006')
       
  1042 datetime.date(2006, 10, 25)
       
  1043 >>> f.clean('25 October 2006')
       
  1044 datetime.date(2006, 10, 25)
       
  1045 >>> f.clean('25 October, 2006')
       
  1046 datetime.date(2006, 10, 25)
       
  1047 >>> f.clean('2006-4-31')
       
  1048 Traceback (most recent call last):
       
  1049 ...
       
  1050 ValidationError: [u'Enter a valid date.']
       
  1051 >>> f.clean('200a-10-25')
       
  1052 Traceback (most recent call last):
       
  1053 ...
       
  1054 ValidationError: [u'Enter a valid date.']
       
  1055 >>> f.clean('25/10/06')
       
  1056 Traceback (most recent call last):
       
  1057 ...
       
  1058 ValidationError: [u'Enter a valid date.']
       
  1059 >>> f.clean(None)
       
  1060 Traceback (most recent call last):
       
  1061 ...
       
  1062 ValidationError: [u'This field is required.']
       
  1063 
       
  1064 >>> f = DateField(required=False)
       
  1065 >>> f.clean(None)
       
  1066 >>> repr(f.clean(None))
       
  1067 'None'
       
  1068 >>> f.clean('')
       
  1069 >>> repr(f.clean(''))
       
  1070 'None'
       
  1071 
       
  1072 DateField accepts an optional input_formats parameter:
       
  1073 >>> f = DateField(input_formats=['%Y %m %d'])
       
  1074 >>> f.clean(datetime.date(2006, 10, 25))
       
  1075 datetime.date(2006, 10, 25)
       
  1076 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
       
  1077 datetime.date(2006, 10, 25)
       
  1078 >>> f.clean('2006 10 25')
       
  1079 datetime.date(2006, 10, 25)
       
  1080 
       
  1081 The input_formats parameter overrides all default input formats,
       
  1082 so the default formats won't work unless you specify them:
       
  1083 >>> f.clean('2006-10-25')
       
  1084 Traceback (most recent call last):
       
  1085 ...
       
  1086 ValidationError: [u'Enter a valid date.']
       
  1087 >>> f.clean('10/25/2006')
       
  1088 Traceback (most recent call last):
       
  1089 ...
       
  1090 ValidationError: [u'Enter a valid date.']
       
  1091 >>> f.clean('10/25/06')
       
  1092 Traceback (most recent call last):
       
  1093 ...
       
  1094 ValidationError: [u'Enter a valid date.']
       
  1095 
       
  1096 # TimeField ###################################################################
       
  1097 
       
  1098 >>> import datetime
       
  1099 >>> f = TimeField()
       
  1100 >>> f.clean(datetime.time(14, 25))
       
  1101 datetime.time(14, 25)
       
  1102 >>> f.clean(datetime.time(14, 25, 59))
       
  1103 datetime.time(14, 25, 59)
       
  1104 >>> f.clean('14:25')
       
  1105 datetime.time(14, 25)
       
  1106 >>> f.clean('14:25:59')
       
  1107 datetime.time(14, 25, 59)
       
  1108 >>> f.clean('hello')
       
  1109 Traceback (most recent call last):
       
  1110 ...
       
  1111 ValidationError: [u'Enter a valid time.']
       
  1112 >>> f.clean('1:24 p.m.')
       
  1113 Traceback (most recent call last):
       
  1114 ...
       
  1115 ValidationError: [u'Enter a valid time.']
       
  1116 
       
  1117 TimeField accepts an optional input_formats parameter:
       
  1118 >>> f = TimeField(input_formats=['%I:%M %p'])
       
  1119 >>> f.clean(datetime.time(14, 25))
       
  1120 datetime.time(14, 25)
       
  1121 >>> f.clean(datetime.time(14, 25, 59))
       
  1122 datetime.time(14, 25, 59)
       
  1123 >>> f.clean('4:25 AM')
       
  1124 datetime.time(4, 25)
       
  1125 >>> f.clean('4:25 PM')
       
  1126 datetime.time(16, 25)
       
  1127 
       
  1128 The input_formats parameter overrides all default input formats,
       
  1129 so the default formats won't work unless you specify them:
       
  1130 >>> f.clean('14:30:45')
       
  1131 Traceback (most recent call last):
       
  1132 ...
       
  1133 ValidationError: [u'Enter a valid time.']
       
  1134 
       
  1135 # DateTimeField ###############################################################
       
  1136 
       
  1137 >>> import datetime
       
  1138 >>> f = DateTimeField()
       
  1139 >>> f.clean(datetime.date(2006, 10, 25))
       
  1140 datetime.datetime(2006, 10, 25, 0, 0)
       
  1141 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
       
  1142 datetime.datetime(2006, 10, 25, 14, 30)
       
  1143 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
       
  1144 datetime.datetime(2006, 10, 25, 14, 30, 59)
       
  1145 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
       
  1146 datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
       
  1147 >>> f.clean('2006-10-25 14:30:45')
       
  1148 datetime.datetime(2006, 10, 25, 14, 30, 45)
       
  1149 >>> f.clean('2006-10-25 14:30:00')
       
  1150 datetime.datetime(2006, 10, 25, 14, 30)
       
  1151 >>> f.clean('2006-10-25 14:30')
       
  1152 datetime.datetime(2006, 10, 25, 14, 30)
       
  1153 >>> f.clean('2006-10-25')
       
  1154 datetime.datetime(2006, 10, 25, 0, 0)
       
  1155 >>> f.clean('10/25/2006 14:30:45')
       
  1156 datetime.datetime(2006, 10, 25, 14, 30, 45)
       
  1157 >>> f.clean('10/25/2006 14:30:00')
       
  1158 datetime.datetime(2006, 10, 25, 14, 30)
       
  1159 >>> f.clean('10/25/2006 14:30')
       
  1160 datetime.datetime(2006, 10, 25, 14, 30)
       
  1161 >>> f.clean('10/25/2006')
       
  1162 datetime.datetime(2006, 10, 25, 0, 0)
       
  1163 >>> f.clean('10/25/06 14:30:45')
       
  1164 datetime.datetime(2006, 10, 25, 14, 30, 45)
       
  1165 >>> f.clean('10/25/06 14:30:00')
       
  1166 datetime.datetime(2006, 10, 25, 14, 30)
       
  1167 >>> f.clean('10/25/06 14:30')
       
  1168 datetime.datetime(2006, 10, 25, 14, 30)
       
  1169 >>> f.clean('10/25/06')
       
  1170 datetime.datetime(2006, 10, 25, 0, 0)
       
  1171 >>> f.clean('hello')
       
  1172 Traceback (most recent call last):
       
  1173 ...
       
  1174 ValidationError: [u'Enter a valid date/time.']
       
  1175 >>> f.clean('2006-10-25 4:30 p.m.')
       
  1176 Traceback (most recent call last):
       
  1177 ...
       
  1178 ValidationError: [u'Enter a valid date/time.']
       
  1179 
       
  1180 DateField accepts an optional input_formats parameter:
       
  1181 >>> f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
       
  1182 >>> f.clean(datetime.date(2006, 10, 25))
       
  1183 datetime.datetime(2006, 10, 25, 0, 0)
       
  1184 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
       
  1185 datetime.datetime(2006, 10, 25, 14, 30)
       
  1186 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
       
  1187 datetime.datetime(2006, 10, 25, 14, 30, 59)
       
  1188 >>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
       
  1189 datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
       
  1190 >>> f.clean('2006 10 25 2:30 PM')
       
  1191 datetime.datetime(2006, 10, 25, 14, 30)
       
  1192 
       
  1193 The input_formats parameter overrides all default input formats,
       
  1194 so the default formats won't work unless you specify them:
       
  1195 >>> f.clean('2006-10-25 14:30:45')
       
  1196 Traceback (most recent call last):
       
  1197 ...
       
  1198 ValidationError: [u'Enter a valid date/time.']
       
  1199 
       
  1200 >>> f = DateTimeField(required=False)
       
  1201 >>> f.clean(None)
       
  1202 >>> repr(f.clean(None))
       
  1203 'None'
       
  1204 >>> f.clean('')
       
  1205 >>> repr(f.clean(''))
       
  1206 'None'
       
  1207 
       
  1208 # RegexField ##################################################################
       
  1209 
       
  1210 >>> f = RegexField('^\d[A-F]\d$')
       
  1211 >>> f.clean('2A2')
       
  1212 u'2A2'
       
  1213 >>> f.clean('3F3')
       
  1214 u'3F3'
       
  1215 >>> f.clean('3G3')
       
  1216 Traceback (most recent call last):
       
  1217 ...
       
  1218 ValidationError: [u'Enter a valid value.']
       
  1219 >>> f.clean(' 2A2')
       
  1220 Traceback (most recent call last):
       
  1221 ...
       
  1222 ValidationError: [u'Enter a valid value.']
       
  1223 >>> f.clean('2A2 ')
       
  1224 Traceback (most recent call last):
       
  1225 ...
       
  1226 ValidationError: [u'Enter a valid value.']
       
  1227 >>> f.clean('')
       
  1228 Traceback (most recent call last):
       
  1229 ...
       
  1230 ValidationError: [u'This field is required.']
       
  1231 
       
  1232 >>> f = RegexField('^\d[A-F]\d$', required=False)
       
  1233 >>> f.clean('2A2')
       
  1234 u'2A2'
       
  1235 >>> f.clean('3F3')
       
  1236 u'3F3'
       
  1237 >>> f.clean('3G3')
       
  1238 Traceback (most recent call last):
       
  1239 ...
       
  1240 ValidationError: [u'Enter a valid value.']
       
  1241 >>> f.clean('')
       
  1242 u''
       
  1243 
       
  1244 Alternatively, RegexField can take a compiled regular expression:
       
  1245 >>> f = RegexField(re.compile('^\d[A-F]\d$'))
       
  1246 >>> f.clean('2A2')
       
  1247 u'2A2'
       
  1248 >>> f.clean('3F3')
       
  1249 u'3F3'
       
  1250 >>> f.clean('3G3')
       
  1251 Traceback (most recent call last):
       
  1252 ...
       
  1253 ValidationError: [u'Enter a valid value.']
       
  1254 >>> f.clean(' 2A2')
       
  1255 Traceback (most recent call last):
       
  1256 ...
       
  1257 ValidationError: [u'Enter a valid value.']
       
  1258 >>> f.clean('2A2 ')
       
  1259 Traceback (most recent call last):
       
  1260 ...
       
  1261 ValidationError: [u'Enter a valid value.']
       
  1262 
       
  1263 RegexField takes an optional error_message argument:
       
  1264 >>> f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.')
       
  1265 >>> f.clean('1234')
       
  1266 u'1234'
       
  1267 >>> f.clean('123')
       
  1268 Traceback (most recent call last):
       
  1269 ...
       
  1270 ValidationError: [u'Enter a four-digit number.']
       
  1271 >>> f.clean('abcd')
       
  1272 Traceback (most recent call last):
       
  1273 ...
       
  1274 ValidationError: [u'Enter a four-digit number.']
       
  1275 
       
  1276 RegexField also access min_length and max_length parameters, for convenience.
       
  1277 >>> f = RegexField('^\d+$', min_length=5, max_length=10)
       
  1278 >>> f.clean('123')
       
  1279 Traceback (most recent call last):
       
  1280 ...
       
  1281 ValidationError: [u'Ensure this value has at least 5 characters.']
       
  1282 >>> f.clean('abc')
       
  1283 Traceback (most recent call last):
       
  1284 ...
       
  1285 ValidationError: [u'Ensure this value has at least 5 characters.']
       
  1286 >>> f.clean('12345')
       
  1287 u'12345'
       
  1288 >>> f.clean('1234567890')
       
  1289 u'1234567890'
       
  1290 >>> f.clean('12345678901')
       
  1291 Traceback (most recent call last):
       
  1292 ...
       
  1293 ValidationError: [u'Ensure this value has at most 10 characters.']
       
  1294 >>> f.clean('12345a')
       
  1295 Traceback (most recent call last):
       
  1296 ...
       
  1297 ValidationError: [u'Enter a valid value.']
       
  1298 
       
  1299 # EmailField ##################################################################
       
  1300 
       
  1301 >>> f = EmailField()
       
  1302 >>> f.clean('')
       
  1303 Traceback (most recent call last):
       
  1304 ...
       
  1305 ValidationError: [u'This field is required.']
       
  1306 >>> f.clean(None)
       
  1307 Traceback (most recent call last):
       
  1308 ...
       
  1309 ValidationError: [u'This field is required.']
       
  1310 >>> f.clean('person@example.com')
       
  1311 u'person@example.com'
       
  1312 >>> f.clean('foo')
       
  1313 Traceback (most recent call last):
       
  1314 ...
       
  1315 ValidationError: [u'Enter a valid e-mail address.']
       
  1316 >>> f.clean('foo@')
       
  1317 Traceback (most recent call last):
       
  1318 ...
       
  1319 ValidationError: [u'Enter a valid e-mail address.']
       
  1320 >>> f.clean('foo@bar')
       
  1321 Traceback (most recent call last):
       
  1322 ...
       
  1323 ValidationError: [u'Enter a valid e-mail address.']
       
  1324 
       
  1325 >>> f = EmailField(required=False)
       
  1326 >>> f.clean('')
       
  1327 u''
       
  1328 >>> f.clean(None)
       
  1329 u''
       
  1330 >>> f.clean('person@example.com')
       
  1331 u'person@example.com'
       
  1332 >>> f.clean('foo')
       
  1333 Traceback (most recent call last):
       
  1334 ...
       
  1335 ValidationError: [u'Enter a valid e-mail address.']
       
  1336 >>> f.clean('foo@')
       
  1337 Traceback (most recent call last):
       
  1338 ...
       
  1339 ValidationError: [u'Enter a valid e-mail address.']
       
  1340 >>> f.clean('foo@bar')
       
  1341 Traceback (most recent call last):
       
  1342 ...
       
  1343 ValidationError: [u'Enter a valid e-mail address.']
       
  1344 
       
  1345 EmailField also access min_length and max_length parameters, for convenience.
       
  1346 >>> f = EmailField(min_length=10, max_length=15)
       
  1347 >>> f.clean('a@foo.com')
       
  1348 Traceback (most recent call last):
       
  1349 ...
       
  1350 ValidationError: [u'Ensure this value has at least 10 characters.']
       
  1351 >>> f.clean('alf@foo.com')
       
  1352 u'alf@foo.com'
       
  1353 >>> f.clean('alf123456788@foo.com')
       
  1354 Traceback (most recent call last):
       
  1355 ...
       
  1356 ValidationError: [u'Ensure this value has at most 15 characters.']
       
  1357 
       
  1358 # URLField ##################################################################
       
  1359 
       
  1360 >>> f = URLField()
       
  1361 >>> f.clean('')
       
  1362 Traceback (most recent call last):
       
  1363 ...
       
  1364 ValidationError: [u'This field is required.']
       
  1365 >>> f.clean(None)
       
  1366 Traceback (most recent call last):
       
  1367 ...
       
  1368 ValidationError: [u'This field is required.']
       
  1369 >>> f.clean('http://example.com')
       
  1370 u'http://example.com'
       
  1371 >>> f.clean('http://www.example.com')
       
  1372 u'http://www.example.com'
       
  1373 >>> f.clean('foo')
       
  1374 Traceback (most recent call last):
       
  1375 ...
       
  1376 ValidationError: [u'Enter a valid URL.']
       
  1377 >>> f.clean('example.com')
       
  1378 Traceback (most recent call last):
       
  1379 ...
       
  1380 ValidationError: [u'Enter a valid URL.']
       
  1381 >>> f.clean('http://')
       
  1382 Traceback (most recent call last):
       
  1383 ...
       
  1384 ValidationError: [u'Enter a valid URL.']
       
  1385 >>> f.clean('http://example')
       
  1386 Traceback (most recent call last):
       
  1387 ...
       
  1388 ValidationError: [u'Enter a valid URL.']
       
  1389 >>> f.clean('http://example.')
       
  1390 Traceback (most recent call last):
       
  1391 ...
       
  1392 ValidationError: [u'Enter a valid URL.']
       
  1393 >>> f.clean('http://.com')
       
  1394 Traceback (most recent call last):
       
  1395 ...
       
  1396 ValidationError: [u'Enter a valid URL.']
       
  1397 
       
  1398 >>> f = URLField(required=False)
       
  1399 >>> f.clean('')
       
  1400 u''
       
  1401 >>> f.clean(None)
       
  1402 u''
       
  1403 >>> f.clean('http://example.com')
       
  1404 u'http://example.com'
       
  1405 >>> f.clean('http://www.example.com')
       
  1406 u'http://www.example.com'
       
  1407 >>> f.clean('foo')
       
  1408 Traceback (most recent call last):
       
  1409 ...
       
  1410 ValidationError: [u'Enter a valid URL.']
       
  1411 >>> f.clean('example.com')
       
  1412 Traceback (most recent call last):
       
  1413 ...
       
  1414 ValidationError: [u'Enter a valid URL.']
       
  1415 >>> f.clean('http://')
       
  1416 Traceback (most recent call last):
       
  1417 ...
       
  1418 ValidationError: [u'Enter a valid URL.']
       
  1419 >>> f.clean('http://example')
       
  1420 Traceback (most recent call last):
       
  1421 ...
       
  1422 ValidationError: [u'Enter a valid URL.']
       
  1423 >>> f.clean('http://example.')
       
  1424 Traceback (most recent call last):
       
  1425 ...
       
  1426 ValidationError: [u'Enter a valid URL.']
       
  1427 >>> f.clean('http://.com')
       
  1428 Traceback (most recent call last):
       
  1429 ...
       
  1430 ValidationError: [u'Enter a valid URL.']
       
  1431 
       
  1432 URLField takes an optional verify_exists parameter, which is False by default.
       
  1433 This verifies that the URL is live on the Internet and doesn't return a 404 or 500:
       
  1434 >>> f = URLField(verify_exists=True)
       
  1435 >>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
       
  1436 u'http://www.google.com'
       
  1437 >>> f.clean('http://example')
       
  1438 Traceback (most recent call last):
       
  1439 ...
       
  1440 ValidationError: [u'Enter a valid URL.']
       
  1441 >>> f.clean('http://www.jfoiwjfoi23jfoijoaijfoiwjofiwjefewl.com') # bad domain
       
  1442 Traceback (most recent call last):
       
  1443 ...
       
  1444 ValidationError: [u'This URL appears to be a broken link.']
       
  1445 >>> f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
       
  1446 Traceback (most recent call last):
       
  1447 ...
       
  1448 ValidationError: [u'This URL appears to be a broken link.']
       
  1449 >>> f = URLField(verify_exists=True, required=False)
       
  1450 >>> f.clean('')
       
  1451 u''
       
  1452 >>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
       
  1453 u'http://www.google.com'
       
  1454 
       
  1455 EmailField also access min_length and max_length parameters, for convenience.
       
  1456 >>> f = URLField(min_length=15, max_length=20)
       
  1457 >>> f.clean('http://f.com')
       
  1458 Traceback (most recent call last):
       
  1459 ...
       
  1460 ValidationError: [u'Ensure this value has at least 15 characters.']
       
  1461 >>> f.clean('http://example.com')
       
  1462 u'http://example.com'
       
  1463 >>> f.clean('http://abcdefghijklmnopqrstuvwxyz.com')
       
  1464 Traceback (most recent call last):
       
  1465 ...
       
  1466 ValidationError: [u'Ensure this value has at most 20 characters.']
       
  1467 
       
  1468 # BooleanField ################################################################
       
  1469 
       
  1470 >>> f = BooleanField()
       
  1471 >>> f.clean('')
       
  1472 Traceback (most recent call last):
       
  1473 ...
       
  1474 ValidationError: [u'This field is required.']
       
  1475 >>> f.clean(None)
       
  1476 Traceback (most recent call last):
       
  1477 ...
       
  1478 ValidationError: [u'This field is required.']
       
  1479 >>> f.clean(True)
       
  1480 True
       
  1481 >>> f.clean(False)
       
  1482 False
       
  1483 >>> f.clean(1)
       
  1484 True
       
  1485 >>> f.clean(0)
       
  1486 False
       
  1487 >>> f.clean('Django rocks')
       
  1488 True
       
  1489 
       
  1490 >>> f = BooleanField(required=False)
       
  1491 >>> f.clean('')
       
  1492 False
       
  1493 >>> f.clean(None)
       
  1494 False
       
  1495 >>> f.clean(True)
       
  1496 True
       
  1497 >>> f.clean(False)
       
  1498 False
       
  1499 >>> f.clean(1)
       
  1500 True
       
  1501 >>> f.clean(0)
       
  1502 False
       
  1503 >>> f.clean('Django rocks')
       
  1504 True
       
  1505 
       
  1506 # ChoiceField #################################################################
       
  1507 
       
  1508 >>> f = ChoiceField(choices=[('1', '1'), ('2', '2')])
       
  1509 >>> f.clean('')
       
  1510 Traceback (most recent call last):
       
  1511 ...
       
  1512 ValidationError: [u'This field is required.']
       
  1513 >>> f.clean(None)
       
  1514 Traceback (most recent call last):
       
  1515 ...
       
  1516 ValidationError: [u'This field is required.']
       
  1517 >>> f.clean(1)
       
  1518 u'1'
       
  1519 >>> f.clean('1')
       
  1520 u'1'
       
  1521 >>> f.clean('3')
       
  1522 Traceback (most recent call last):
       
  1523 ...
       
  1524 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
       
  1525 
       
  1526 >>> f = ChoiceField(choices=[('1', '1'), ('2', '2')], required=False)
       
  1527 >>> f.clean('')
       
  1528 u''
       
  1529 >>> f.clean(None)
       
  1530 u''
       
  1531 >>> f.clean(1)
       
  1532 u'1'
       
  1533 >>> f.clean('1')
       
  1534 u'1'
       
  1535 >>> f.clean('3')
       
  1536 Traceback (most recent call last):
       
  1537 ...
       
  1538 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
       
  1539 
       
  1540 >>> f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
       
  1541 >>> f.clean('J')
       
  1542 u'J'
       
  1543 >>> f.clean('John')
       
  1544 Traceback (most recent call last):
       
  1545 ...
       
  1546 ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
       
  1547 
       
  1548 # NullBooleanField ############################################################
       
  1549 
       
  1550 >>> f = NullBooleanField()
       
  1551 >>> f.clean('')
       
  1552 >>> f.clean(True)
       
  1553 True
       
  1554 >>> f.clean(False)
       
  1555 False
       
  1556 >>> f.clean(None)
       
  1557 >>> f.clean('1')
       
  1558 >>> f.clean('2')
       
  1559 >>> f.clean('3')
       
  1560 >>> f.clean('hello')
       
  1561 
       
  1562 # MultipleChoiceField #########################################################
       
  1563 
       
  1564 >>> f = MultipleChoiceField(choices=[('1', '1'), ('2', '2')])
       
  1565 >>> f.clean('')
       
  1566 Traceback (most recent call last):
       
  1567 ...
       
  1568 ValidationError: [u'This field is required.']
       
  1569 >>> f.clean(None)
       
  1570 Traceback (most recent call last):
       
  1571 ...
       
  1572 ValidationError: [u'This field is required.']
       
  1573 >>> f.clean([1])
       
  1574 [u'1']
       
  1575 >>> f.clean(['1'])
       
  1576 [u'1']
       
  1577 >>> f.clean(['1', '2'])
       
  1578 [u'1', u'2']
       
  1579 >>> f.clean([1, '2'])
       
  1580 [u'1', u'2']
       
  1581 >>> f.clean((1, '2'))
       
  1582 [u'1', u'2']
       
  1583 >>> f.clean('hello')
       
  1584 Traceback (most recent call last):
       
  1585 ...
       
  1586 ValidationError: [u'Enter a list of values.']
       
  1587 >>> f.clean([])
       
  1588 Traceback (most recent call last):
       
  1589 ...
       
  1590 ValidationError: [u'This field is required.']
       
  1591 >>> f.clean(())
       
  1592 Traceback (most recent call last):
       
  1593 ...
       
  1594 ValidationError: [u'This field is required.']
       
  1595 >>> f.clean(['3'])
       
  1596 Traceback (most recent call last):
       
  1597 ...
       
  1598 ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
       
  1599 
       
  1600 >>> f = MultipleChoiceField(choices=[('1', '1'), ('2', '2')], required=False)
       
  1601 >>> f.clean('')
       
  1602 []
       
  1603 >>> f.clean(None)
       
  1604 []
       
  1605 >>> f.clean([1])
       
  1606 [u'1']
       
  1607 >>> f.clean(['1'])
       
  1608 [u'1']
       
  1609 >>> f.clean(['1', '2'])
       
  1610 [u'1', u'2']
       
  1611 >>> f.clean([1, '2'])
       
  1612 [u'1', u'2']
       
  1613 >>> f.clean((1, '2'))
       
  1614 [u'1', u'2']
       
  1615 >>> f.clean('hello')
       
  1616 Traceback (most recent call last):
       
  1617 ...
       
  1618 ValidationError: [u'Enter a list of values.']
       
  1619 >>> f.clean([])
       
  1620 []
       
  1621 >>> f.clean(())
       
  1622 []
       
  1623 >>> f.clean(['3'])
       
  1624 Traceback (most recent call last):
       
  1625 ...
       
  1626 ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
       
  1627 
       
  1628 # ComboField ##################################################################
       
  1629 
       
  1630 ComboField takes a list of fields that should be used to validate a value,
       
  1631 in that order.
       
  1632 >>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
       
  1633 >>> f.clean('test@example.com')
       
  1634 u'test@example.com'
       
  1635 >>> f.clean('longemailaddress@example.com')
       
  1636 Traceback (most recent call last):
       
  1637 ...
       
  1638 ValidationError: [u'Ensure this value has at most 20 characters.']
       
  1639 >>> f.clean('not an e-mail')
       
  1640 Traceback (most recent call last):
       
  1641 ...
       
  1642 ValidationError: [u'Enter a valid e-mail address.']
       
  1643 >>> f.clean('')
       
  1644 Traceback (most recent call last):
       
  1645 ...
       
  1646 ValidationError: [u'This field is required.']
       
  1647 >>> f.clean(None)
       
  1648 Traceback (most recent call last):
       
  1649 ...
       
  1650 ValidationError: [u'This field is required.']
       
  1651 
       
  1652 >>> f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False)
       
  1653 >>> f.clean('test@example.com')
       
  1654 u'test@example.com'
       
  1655 >>> f.clean('longemailaddress@example.com')
       
  1656 Traceback (most recent call last):
       
  1657 ...
       
  1658 ValidationError: [u'Ensure this value has at most 20 characters.']
       
  1659 >>> f.clean('not an e-mail')
       
  1660 Traceback (most recent call last):
       
  1661 ...
       
  1662 ValidationError: [u'Enter a valid e-mail address.']
       
  1663 >>> f.clean('')
       
  1664 u''
       
  1665 >>> f.clean(None)
       
  1666 u''
       
  1667 
       
  1668 # SplitDateTimeField ##########################################################
       
  1669 
       
  1670 >>> f = SplitDateTimeField()
       
  1671 >>> f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
       
  1672 datetime.datetime(2006, 1, 10, 7, 30)
       
  1673 >>> f.clean(None)
       
  1674 Traceback (most recent call last):
       
  1675 ...
       
  1676 ValidationError: [u'This field is required.']
       
  1677 >>> f.clean('')
       
  1678 Traceback (most recent call last):
       
  1679 ...
       
  1680 ValidationError: [u'This field is required.']
       
  1681 >>> f.clean('hello')
       
  1682 Traceback (most recent call last):
       
  1683 ...
       
  1684 ValidationError: [u'Enter a list of values.']
       
  1685 >>> f.clean(['hello', 'there'])
       
  1686 Traceback (most recent call last):
       
  1687 ...
       
  1688 ValidationError: [u'Enter a valid date.', u'Enter a valid time.']
       
  1689 >>> f.clean(['2006-01-10', 'there'])
       
  1690 Traceback (most recent call last):
       
  1691 ...
       
  1692 ValidationError: [u'Enter a valid time.']
       
  1693 >>> f.clean(['hello', '07:30'])
       
  1694 Traceback (most recent call last):
       
  1695 ...
       
  1696 ValidationError: [u'Enter a valid date.']
       
  1697 
       
  1698 >>> f = SplitDateTimeField(required=False)
       
  1699 >>> f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
       
  1700 datetime.datetime(2006, 1, 10, 7, 30)
       
  1701 >>> f.clean(None)
       
  1702 >>> f.clean('')
       
  1703 >>> f.clean('hello')
       
  1704 Traceback (most recent call last):
       
  1705 ...
       
  1706 ValidationError: [u'Enter a list of values.']
       
  1707 >>> f.clean(['hello', 'there'])
       
  1708 Traceback (most recent call last):
       
  1709 ...
       
  1710 ValidationError: [u'Enter a valid date.', u'Enter a valid time.']
       
  1711 >>> f.clean(['2006-01-10', 'there'])
       
  1712 Traceback (most recent call last):
       
  1713 ...
       
  1714 ValidationError: [u'Enter a valid time.']
       
  1715 >>> f.clean(['hello', '07:30'])
       
  1716 Traceback (most recent call last):
       
  1717 ...
       
  1718 ValidationError: [u'Enter a valid date.']
       
  1719 
       
  1720 #########
       
  1721 # Forms #
       
  1722 #########
       
  1723 
       
  1724 A Form is a collection of Fields. It knows how to validate a set of data and it
       
  1725 knows how to render itself in a couple of default ways (e.g., an HTML table).
       
  1726 You can pass it data in __init__(), as a dictionary.
       
  1727 
       
  1728 # Form ########################################################################
       
  1729 
       
  1730 >>> class Person(Form):
       
  1731 ...     first_name = CharField()
       
  1732 ...     last_name = CharField()
       
  1733 ...     birthday = DateField()
       
  1734 
       
  1735 Pass a dictionary to a Form's __init__().
       
  1736 >>> p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'})
       
  1737 >>> p.is_bound
       
  1738 True
       
  1739 >>> p.errors
       
  1740 {}
       
  1741 >>> p.is_valid()
       
  1742 True
       
  1743 >>> p.errors.as_ul()
       
  1744 u''
       
  1745 >>> p.errors.as_text()
       
  1746 u''
       
  1747 >>> p.clean_data
       
  1748 {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
       
  1749 >>> print p['first_name']
       
  1750 <input type="text" name="first_name" value="John" id="id_first_name" />
       
  1751 >>> print p['last_name']
       
  1752 <input type="text" name="last_name" value="Lennon" id="id_last_name" />
       
  1753 >>> print p['birthday']
       
  1754 <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
       
  1755 >>> print p['nonexistentfield']
       
  1756 Traceback (most recent call last):
       
  1757 ...
       
  1758 KeyError: "Key 'nonexistentfield' not found in Form"
       
  1759 
       
  1760 >>> for boundfield in p:
       
  1761 ...     print boundfield
       
  1762 <input type="text" name="first_name" value="John" id="id_first_name" />
       
  1763 <input type="text" name="last_name" value="Lennon" id="id_last_name" />
       
  1764 <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
       
  1765 >>> for boundfield in p:
       
  1766 ...     print boundfield.label, boundfield.data
       
  1767 First name John
       
  1768 Last name Lennon
       
  1769 Birthday 1940-10-9
       
  1770 >>> print p
       
  1771 <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>
       
  1772 <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>
       
  1773 <tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>
       
  1774 
       
  1775 Empty dictionaries are valid, too.
       
  1776 >>> p = Person({})
       
  1777 >>> p.is_bound
       
  1778 True
       
  1779 >>> p.errors
       
  1780 {'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
       
  1781 >>> p.is_valid()
       
  1782 False
       
  1783 >>> p.clean_data
       
  1784 Traceback (most recent call last):
       
  1785 ...
       
  1786 AttributeError: 'Person' object has no attribute 'clean_data'
       
  1787 >>> print p
       
  1788 <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>
       
  1789 <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>
       
  1790 <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>
       
  1791 >>> print p.as_table()
       
  1792 <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>
       
  1793 <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>
       
  1794 <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>
       
  1795 >>> print p.as_ul()
       
  1796 <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>
       
  1797 <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>
       
  1798 <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>
       
  1799 >>> print p.as_p()
       
  1800 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
       
  1801 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
       
  1802 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
       
  1803 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
       
  1804 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
       
  1805 <p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
       
  1806 
       
  1807 If you don't pass any values to the Form's __init__(), or if you pass None,
       
  1808 the Form will be considered unbound and won't do any validation. Form.errors
       
  1809 will be an empty dictionary *but* Form.is_valid() will return False.
       
  1810 >>> p = Person()
       
  1811 >>> p.is_bound
       
  1812 False
       
  1813 >>> p.errors
       
  1814 {}
       
  1815 >>> p.is_valid()
       
  1816 False
       
  1817 >>> p.clean_data
       
  1818 Traceback (most recent call last):
       
  1819 ...
       
  1820 AttributeError: 'Person' object has no attribute 'clean_data'
       
  1821 >>> print p
       
  1822 <tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
       
  1823 <tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
       
  1824 <tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
       
  1825 >>> print p.as_table()
       
  1826 <tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
       
  1827 <tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
       
  1828 <tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
       
  1829 >>> print p.as_ul()
       
  1830 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
       
  1831 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
       
  1832 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li>
       
  1833 >>> print p.as_p()
       
  1834 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
       
  1835 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
       
  1836 <p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
       
  1837 
       
  1838 Unicode values are handled properly.
       
  1839 >>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'})
       
  1840 >>> p.as_table()
       
  1841 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>'
       
  1842 >>> p.as_ul()
       
  1843 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>'
       
  1844 >>> p.as_p()
       
  1845 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>'
       
  1846 
       
  1847 >>> p = Person({'last_name': u'Lennon'})
       
  1848 >>> p.errors
       
  1849 {'first_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
       
  1850 >>> p.is_valid()
       
  1851 False
       
  1852 >>> p.errors.as_ul()
       
  1853 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>'
       
  1854 >>> print p.errors.as_text()
       
  1855 * first_name
       
  1856   * This field is required.
       
  1857 * birthday
       
  1858   * This field is required.
       
  1859 >>> p.clean_data
       
  1860 Traceback (most recent call last):
       
  1861 ...
       
  1862 AttributeError: 'Person' object has no attribute 'clean_data'
       
  1863 >>> p['first_name'].errors
       
  1864 [u'This field is required.']
       
  1865 >>> p['first_name'].errors.as_ul()
       
  1866 u'<ul class="errorlist"><li>This field is required.</li></ul>'
       
  1867 >>> p['first_name'].errors.as_text()
       
  1868 u'* This field is required.'
       
  1869 
       
  1870 >>> p = Person()
       
  1871 >>> print p['first_name']
       
  1872 <input type="text" name="first_name" id="id_first_name" />
       
  1873 >>> print p['last_name']
       
  1874 <input type="text" name="last_name" id="id_last_name" />
       
  1875 >>> print p['birthday']
       
  1876 <input type="text" name="birthday" id="id_birthday" />
       
  1877 
       
  1878 clean_data will always *only* contain a key for fields defined in the
       
  1879 Form, even if you pass extra data when you define the Form. In this
       
  1880 example, we pass a bunch of extra fields to the form constructor,
       
  1881 but clean_data contains only the form's fields.
       
  1882 >>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'}
       
  1883 >>> p = Person(data)
       
  1884 >>> p.is_valid()
       
  1885 True
       
  1886 >>> p.clean_data
       
  1887 {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
       
  1888 
       
  1889 "auto_id" tells the Form to add an "id" attribute to each form element.
       
  1890 If it's a string that contains '%s', Django will use that as a format string
       
  1891 into which the field's name will be inserted. It will also put a <label> around
       
  1892 the human-readable labels for a field.
       
  1893 >>> p = Person(auto_id='%s_id')
       
  1894 >>> print p.as_table()
       
  1895 <tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
       
  1896 <tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr>
       
  1897 <tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>
       
  1898 >>> print p.as_ul()
       
  1899 <li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
       
  1900 <li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li>
       
  1901 <li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>
       
  1902 >>> print p.as_p()
       
  1903 <p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
       
  1904 <p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p>
       
  1905 <p><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>
       
  1906 
       
  1907 If auto_id is any True value whose str() does not contain '%s', the "id"
       
  1908 attribute will be the name of the field.
       
  1909 >>> p = Person(auto_id=True)
       
  1910 >>> print p.as_ul()
       
  1911 <li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
       
  1912 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
       
  1913 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
       
  1914 
       
  1915 If auto_id is any False value, an "id" attribute won't be output unless it
       
  1916 was manually entered.
       
  1917 >>> p = Person(auto_id=False)
       
  1918 >>> print p.as_ul()
       
  1919 <li>First name: <input type="text" name="first_name" /></li>
       
  1920 <li>Last name: <input type="text" name="last_name" /></li>
       
  1921 <li>Birthday: <input type="text" name="birthday" /></li>
       
  1922 
       
  1923 In this example, auto_id is False, but the "id" attribute for the "first_name"
       
  1924 field is given. Also note that field gets a <label>, while the others don't.
       
  1925 >>> class PersonNew(Form):
       
  1926 ...     first_name = CharField(widget=TextInput(attrs={'id': 'first_name_id'}))
       
  1927 ...     last_name = CharField()
       
  1928 ...     birthday = DateField()
       
  1929 >>> p = PersonNew(auto_id=False)
       
  1930 >>> print p.as_ul()
       
  1931 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
       
  1932 <li>Last name: <input type="text" name="last_name" /></li>
       
  1933 <li>Birthday: <input type="text" name="birthday" /></li>
       
  1934 
       
  1935 If the "id" attribute is specified in the Form and auto_id is True, the "id"
       
  1936 attribute in the Form gets precedence.
       
  1937 >>> p = PersonNew(auto_id=True)
       
  1938 >>> print p.as_ul()
       
  1939 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
       
  1940 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
       
  1941 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
       
  1942 
       
  1943 >>> class SignupForm(Form):
       
  1944 ...     email = EmailField()
       
  1945 ...     get_spam = BooleanField()
       
  1946 >>> f = SignupForm(auto_id=False)
       
  1947 >>> print f['email']
       
  1948 <input type="text" name="email" />
       
  1949 >>> print f['get_spam']
       
  1950 <input type="checkbox" name="get_spam" />
       
  1951 
       
  1952 >>> f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False)
       
  1953 >>> print f['email']
       
  1954 <input type="text" name="email" value="test@example.com" />
       
  1955 >>> print f['get_spam']
       
  1956 <input checked="checked" type="checkbox" name="get_spam" />
       
  1957 
       
  1958 Any Field can have a Widget class passed to its constructor:
       
  1959 >>> class ContactForm(Form):
       
  1960 ...     subject = CharField()
       
  1961 ...     message = CharField(widget=Textarea)
       
  1962 >>> f = ContactForm(auto_id=False)
       
  1963 >>> print f['subject']
       
  1964 <input type="text" name="subject" />
       
  1965 >>> print f['message']
       
  1966 <textarea name="message"></textarea>
       
  1967 
       
  1968 as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
       
  1969 widget type:
       
  1970 >>> f['subject'].as_textarea()
       
  1971 u'<textarea name="subject"></textarea>'
       
  1972 >>> f['message'].as_text()
       
  1973 u'<input type="text" name="message" />'
       
  1974 >>> f['message'].as_hidden()
       
  1975 u'<input type="hidden" name="message" />'
       
  1976 
       
  1977 The 'widget' parameter to a Field can also be an instance:
       
  1978 >>> class ContactForm(Form):
       
  1979 ...     subject = CharField()
       
  1980 ...     message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20}))
       
  1981 >>> f = ContactForm(auto_id=False)
       
  1982 >>> print f['message']
       
  1983 <textarea rows="80" cols="20" name="message"></textarea>
       
  1984 
       
  1985 Instance-level attrs are *not* carried over to as_textarea(), as_text() and
       
  1986 as_hidden():
       
  1987 >>> f['message'].as_text()
       
  1988 u'<input type="text" name="message" />'
       
  1989 >>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False)
       
  1990 >>> f['subject'].as_textarea()
       
  1991 u'<textarea name="subject">Hello</textarea>'
       
  1992 >>> f['message'].as_text()
       
  1993 u'<input type="text" name="message" value="I love you." />'
       
  1994 >>> f['message'].as_hidden()
       
  1995 u'<input type="hidden" name="message" value="I love you." />'
       
  1996 
       
  1997 For a form with a <select>, use ChoiceField:
       
  1998 >>> class FrameworkForm(Form):
       
  1999 ...     name = CharField()
       
  2000 ...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')])
       
  2001 >>> f = FrameworkForm(auto_id=False)
       
  2002 >>> print f['language']
       
  2003 <select name="language">
       
  2004 <option value="P">Python</option>
       
  2005 <option value="J">Java</option>
       
  2006 </select>
       
  2007 >>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
       
  2008 >>> print f['language']
       
  2009 <select name="language">
       
  2010 <option value="P" selected="selected">Python</option>
       
  2011 <option value="J">Java</option>
       
  2012 </select>
       
  2013 
       
  2014 A subtlety: If one of the choices' value is the empty string and the form is
       
  2015 unbound, then the <option> for the empty-string choice will get selected="selected".
       
  2016 >>> class FrameworkForm(Form):
       
  2017 ...     name = CharField()
       
  2018 ...     language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')])
       
  2019 >>> f = FrameworkForm(auto_id=False)
       
  2020 >>> print f['language']
       
  2021 <select name="language">
       
  2022 <option value="" selected="selected">------</option>
       
  2023 <option value="P">Python</option>
       
  2024 <option value="J">Java</option>
       
  2025 </select>
       
  2026 
       
  2027 You can specify widget attributes in the Widget constructor.
       
  2028 >>> class FrameworkForm(Form):
       
  2029 ...     name = CharField()
       
  2030 ...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(attrs={'class': 'foo'}))
       
  2031 >>> f = FrameworkForm(auto_id=False)
       
  2032 >>> print f['language']
       
  2033 <select class="foo" name="language">
       
  2034 <option value="P">Python</option>
       
  2035 <option value="J">Java</option>
       
  2036 </select>
       
  2037 >>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
       
  2038 >>> print f['language']
       
  2039 <select class="foo" name="language">
       
  2040 <option value="P" selected="selected">Python</option>
       
  2041 <option value="J">Java</option>
       
  2042 </select>
       
  2043 
       
  2044 When passing a custom widget instance to ChoiceField, note that setting
       
  2045 'choices' on the widget is meaningless. The widget will use the choices
       
  2046 defined on the Field, not the ones defined on the Widget.
       
  2047 >>> class FrameworkForm(Form):
       
  2048 ...     name = CharField()
       
  2049 ...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(choices=[('R', 'Ruby'), ('P', 'Perl')], attrs={'class': 'foo'}))
       
  2050 >>> f = FrameworkForm(auto_id=False)
       
  2051 >>> print f['language']
       
  2052 <select class="foo" name="language">
       
  2053 <option value="P">Python</option>
       
  2054 <option value="J">Java</option>
       
  2055 </select>
       
  2056 >>> f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
       
  2057 >>> print f['language']
       
  2058 <select class="foo" name="language">
       
  2059 <option value="P" selected="selected">Python</option>
       
  2060 <option value="J">Java</option>
       
  2061 </select>
       
  2062 
       
  2063 You can set a ChoiceField's choices after the fact.
       
  2064 >>> class FrameworkForm(Form):
       
  2065 ...     name = CharField()
       
  2066 ...     language = ChoiceField()
       
  2067 >>> f = FrameworkForm(auto_id=False)
       
  2068 >>> print f['language']
       
  2069 <select name="language">
       
  2070 </select>
       
  2071 >>> f.fields['language'].choices = [('P', 'Python'), ('J', 'Java')]
       
  2072 >>> print f['language']
       
  2073 <select name="language">
       
  2074 <option value="P">Python</option>
       
  2075 <option value="J">Java</option>
       
  2076 </select>
       
  2077 
       
  2078 Add widget=RadioSelect to use that widget with a ChoiceField.
       
  2079 >>> class FrameworkForm(Form):
       
  2080 ...     name = CharField()
       
  2081 ...     language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=RadioSelect)
       
  2082 >>> f = FrameworkForm(auto_id=False)
       
  2083 >>> print f['language']
       
  2084 <ul>
       
  2085 <li><label><input type="radio" name="language" value="P" /> Python</label></li>
       
  2086 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
       
  2087 </ul>
       
  2088 >>> print f
       
  2089 <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
       
  2090 <tr><th>Language:</th><td><ul>
       
  2091 <li><label><input type="radio" name="language" value="P" /> Python</label></li>
       
  2092 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
       
  2093 </ul></td></tr>
       
  2094 >>> print f.as_ul()
       
  2095 <li>Name: <input type="text" name="name" /></li>
       
  2096 <li>Language: <ul>
       
  2097 <li><label><input type="radio" name="language" value="P" /> Python</label></li>
       
  2098 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
       
  2099 </ul></li>
       
  2100 
       
  2101 Regarding auto_id and <label>, RadioSelect is a special case. Each radio button
       
  2102 gets a distinct ID, formed by appending an underscore plus the button's
       
  2103 zero-based index.
       
  2104 >>> f = FrameworkForm(auto_id='id_%s')
       
  2105 >>> print f['language']
       
  2106 <ul>
       
  2107 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
       
  2108 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
       
  2109 </ul>
       
  2110 
       
  2111 When RadioSelect is used with auto_id, and the whole form is printed using
       
  2112 either as_table() or as_ul(), the label for the RadioSelect will point to the
       
  2113 ID of the *first* radio button.
       
  2114 >>> print f
       
  2115 <tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" /></td></tr>
       
  2116 <tr><th><label for="id_language_0">Language:</label></th><td><ul>
       
  2117 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
       
  2118 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
       
  2119 </ul></td></tr>
       
  2120 >>> print f.as_ul()
       
  2121 <li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li>
       
  2122 <li><label for="id_language_0">Language:</label> <ul>
       
  2123 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
       
  2124 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
       
  2125 </ul></li>
       
  2126 >>> print f.as_p()
       
  2127 <p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p>
       
  2128 <p><label for="id_language_0">Language:</label> <ul>
       
  2129 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
       
  2130 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
       
  2131 </ul></p>
       
  2132 
       
  2133 MultipleChoiceField is a special case, as its data is required to be a list:
       
  2134 >>> class SongForm(Form):
       
  2135 ...     name = CharField()
       
  2136 ...     composers = MultipleChoiceField()
       
  2137 >>> f = SongForm(auto_id=False)
       
  2138 >>> print f['composers']
       
  2139 <select multiple="multiple" name="composers">
       
  2140 </select>
       
  2141 >>> class SongForm(Form):
       
  2142 ...     name = CharField()
       
  2143 ...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')])
       
  2144 >>> f = SongForm(auto_id=False)
       
  2145 >>> print f['composers']
       
  2146 <select multiple="multiple" name="composers">
       
  2147 <option value="J">John Lennon</option>
       
  2148 <option value="P">Paul McCartney</option>
       
  2149 </select>
       
  2150 >>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
       
  2151 >>> print f['name']
       
  2152 <input type="text" name="name" value="Yesterday" />
       
  2153 >>> print f['composers']
       
  2154 <select multiple="multiple" name="composers">
       
  2155 <option value="J">John Lennon</option>
       
  2156 <option value="P" selected="selected">Paul McCartney</option>
       
  2157 </select>
       
  2158 
       
  2159 MultipleChoiceField rendered as_hidden() is a special case. Because it can
       
  2160 have multiple values, its as_hidden() renders multiple <input type="hidden">
       
  2161 tags.
       
  2162 >>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
       
  2163 >>> print f['composers'].as_hidden()
       
  2164 <input type="hidden" name="composers" value="P" />
       
  2165 >>> f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False)
       
  2166 >>> print f['composers'].as_hidden()
       
  2167 <input type="hidden" name="composers" value="P" />
       
  2168 <input type="hidden" name="composers" value="J" />
       
  2169 
       
  2170 MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
       
  2171 >>> class SongForm(Form):
       
  2172 ...     name = CharField()
       
  2173 ...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple)
       
  2174 >>> f = SongForm(auto_id=False)
       
  2175 >>> print f['composers']
       
  2176 <ul>
       
  2177 <li><label><input type="checkbox" name="composers" value="J" /> John Lennon</label></li>
       
  2178 <li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
       
  2179 </ul>
       
  2180 >>> f = SongForm({'composers': ['J']}, auto_id=False)
       
  2181 >>> print f['composers']
       
  2182 <ul>
       
  2183 <li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
       
  2184 <li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
       
  2185 </ul>
       
  2186 >>> f = SongForm({'composers': ['J', 'P']}, auto_id=False)
       
  2187 >>> print f['composers']
       
  2188 <ul>
       
  2189 <li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
       
  2190 <li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
       
  2191 </ul>
       
  2192 
       
  2193 Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox
       
  2194 gets a distinct ID, formed by appending an underscore plus the checkbox's
       
  2195 zero-based index.
       
  2196 >>> f = SongForm(auto_id='%s_id')
       
  2197 >>> print f['composers']
       
  2198 <ul>
       
  2199 <li><label><input type="checkbox" name="composers" value="J" id="composers_id_0" /> John Lennon</label></li>
       
  2200 <li><label><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li>
       
  2201 </ul>
       
  2202 
       
  2203 Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict
       
  2204 conveniently work with this.
       
  2205 >>> data = {'name': 'Yesterday', 'composers': ['J', 'P']}
       
  2206 >>> f = SongForm(data)
       
  2207 >>> f.errors
       
  2208 {}
       
  2209 >>> from django.http import QueryDict
       
  2210 >>> data = QueryDict('name=Yesterday&composers=J&composers=P')
       
  2211 >>> f = SongForm(data)
       
  2212 >>> f.errors
       
  2213 {}
       
  2214 >>> from django.utils.datastructures import MultiValueDict
       
  2215 >>> data = MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))
       
  2216 >>> f = SongForm(data)
       
  2217 >>> f.errors
       
  2218 {}
       
  2219 
       
  2220 The MultipleHiddenInput widget renders multiple values as hidden fields.
       
  2221 >>> class SongFormHidden(Form):
       
  2222 ...     name = CharField()
       
  2223 ...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=MultipleHiddenInput)
       
  2224 >>> f = SongFormHidden(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])), auto_id=False)
       
  2225 >>> print f.as_ul()
       
  2226 <li>Name: <input type="text" name="name" value="Yesterday" /><input type="hidden" name="composers" value="J" />
       
  2227 <input type="hidden" name="composers" value="P" /></li>
       
  2228 
       
  2229 When using CheckboxSelectMultiple, the framework expects a list of input and
       
  2230 returns a list of input.
       
  2231 >>> f = SongForm({'name': 'Yesterday'}, auto_id=False)
       
  2232 >>> f.errors
       
  2233 {'composers': [u'This field is required.']}
       
  2234 >>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
       
  2235 >>> f.errors
       
  2236 {}
       
  2237 >>> f.clean_data
       
  2238 {'composers': [u'J'], 'name': u'Yesterday'}
       
  2239 >>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
       
  2240 >>> f.errors
       
  2241 {}
       
  2242 >>> f.clean_data
       
  2243 {'composers': [u'J', u'P'], 'name': u'Yesterday'}
       
  2244 
       
  2245 Validation errors are HTML-escaped when output as HTML.
       
  2246 >>> class EscapingForm(Form):
       
  2247 ...     special_name = CharField()
       
  2248 ...     def clean_special_name(self):
       
  2249 ...         raise ValidationError("Something's wrong with '%s'" % self.clean_data['special_name'])
       
  2250 
       
  2251 >>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
       
  2252 >>> print f
       
  2253 <tr><th>Special name:</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>
       
  2254 >>> f = EscapingForm({'special_name': "Should escape < & > and <script>alert('xss')</script>"}, auto_id=False)
       
  2255 >>> print f
       
  2256 <tr><th>Special name:</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>
       
  2257 
       
  2258 # Validating multiple fields in relation to another ###########################
       
  2259 
       
  2260 There are a couple of ways to do multiple-field validation. If you want the
       
  2261 validation message to be associated with a particular field, implement the
       
  2262 clean_XXX() method on the Form, where XXX is the field name. As in
       
  2263 Field.clean(), the clean_XXX() method should return the cleaned value. In the
       
  2264 clean_XXX() method, you have access to self.clean_data, which is a dictionary
       
  2265 of all the data that has been cleaned *so far*, in order by the fields,
       
  2266 including the current field (e.g., the field XXX if you're in clean_XXX()).
       
  2267 >>> class UserRegistration(Form):
       
  2268 ...    username = CharField(max_length=10)
       
  2269 ...    password1 = CharField(widget=PasswordInput)
       
  2270 ...    password2 = CharField(widget=PasswordInput)
       
  2271 ...    def clean_password2(self):
       
  2272 ...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
       
  2273 ...            raise ValidationError(u'Please make sure your passwords match.')
       
  2274 ...        return self.clean_data['password2']
       
  2275 >>> f = UserRegistration(auto_id=False)
       
  2276 >>> f.errors
       
  2277 {}
       
  2278 >>> f = UserRegistration({}, auto_id=False)
       
  2279 >>> f.errors
       
  2280 {'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
       
  2281 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
       
  2282 >>> f.errors
       
  2283 {'password2': [u'Please make sure your passwords match.']}
       
  2284 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
       
  2285 >>> f.errors
       
  2286 {}
       
  2287 >>> f.clean_data
       
  2288 {'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
       
  2289 
       
  2290 Another way of doing multiple-field validation is by implementing the
       
  2291 Form's clean() method. If you do this, any ValidationError raised by that
       
  2292 method will not be associated with a particular field; it will have a
       
  2293 special-case association with the field named '__all__'.
       
  2294 Note that in Form.clean(), you have access to self.clean_data, a dictionary of
       
  2295 all the fields/values that have *not* raised a ValidationError. Also note
       
  2296 Form.clean() is required to return a dictionary of all clean data.
       
  2297 >>> class UserRegistration(Form):
       
  2298 ...    username = CharField(max_length=10)
       
  2299 ...    password1 = CharField(widget=PasswordInput)
       
  2300 ...    password2 = CharField(widget=PasswordInput)
       
  2301 ...    def clean(self):
       
  2302 ...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
       
  2303 ...            raise ValidationError(u'Please make sure your passwords match.')
       
  2304 ...        return self.clean_data
       
  2305 >>> f = UserRegistration(auto_id=False)
       
  2306 >>> f.errors
       
  2307 {}
       
  2308 >>> f = UserRegistration({}, auto_id=False)
       
  2309 >>> print f.as_table()
       
  2310 <tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
       
  2311 <tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
       
  2312 <tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
       
  2313 >>> f.errors
       
  2314 {'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
       
  2315 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
       
  2316 >>> f.errors
       
  2317 {'__all__': [u'Please make sure your passwords match.']}
       
  2318 >>> print f.as_table()
       
  2319 <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
       
  2320 <tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
       
  2321 <tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
       
  2322 <tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
       
  2323 >>> print f.as_ul()
       
  2324 <li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li>
       
  2325 <li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
       
  2326 <li>Password1: <input type="password" name="password1" value="foo" /></li>
       
  2327 <li>Password2: <input type="password" name="password2" value="bar" /></li>
       
  2328 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
       
  2329 >>> f.errors
       
  2330 {}
       
  2331 >>> f.clean_data
       
  2332 {'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
       
  2333 
       
  2334 # Dynamic construction ########################################################
       
  2335 
       
  2336 It's possible to construct a Form dynamically by adding to the self.fields
       
  2337 dictionary in __init__(). Don't forget to call Form.__init__() within the
       
  2338 subclass' __init__().
       
  2339 >>> class Person(Form):
       
  2340 ...     first_name = CharField()
       
  2341 ...     last_name = CharField()
       
  2342 ...     def __init__(self, *args, **kwargs):
       
  2343 ...         super(Person, self).__init__(*args, **kwargs)
       
  2344 ...         self.fields['birthday'] = DateField()
       
  2345 >>> p = Person(auto_id=False)
       
  2346 >>> print p
       
  2347 <tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
       
  2348 <tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
       
  2349 <tr><th>Birthday:</th><td><input type="text" name="birthday" /></td></tr>
       
  2350 
       
  2351 Instances of a dynamic Form do not persist fields from one Form instance to
       
  2352 the next.
       
  2353 >>> class MyForm(Form):
       
  2354 ...     def __init__(self, data=None, auto_id=False, field_list=[]):
       
  2355 ...         Form.__init__(self, data, auto_id)
       
  2356 ...         for field in field_list:
       
  2357 ...             self.fields[field[0]] = field[1]
       
  2358 >>> field_list = [('field1', CharField()), ('field2', CharField())]
       
  2359 >>> my_form = MyForm(field_list=field_list)
       
  2360 >>> print my_form
       
  2361 <tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
       
  2362 <tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
       
  2363 >>> field_list = [('field3', CharField()), ('field4', CharField())]
       
  2364 >>> my_form = MyForm(field_list=field_list)
       
  2365 >>> print my_form
       
  2366 <tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
       
  2367 <tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
       
  2368 
       
  2369 >>> class MyForm(Form):
       
  2370 ...     default_field_1 = CharField()
       
  2371 ...     default_field_2 = CharField()
       
  2372 ...     def __init__(self, data=None, auto_id=False, field_list=[]):
       
  2373 ...         Form.__init__(self, data, auto_id)
       
  2374 ...         for field in field_list:
       
  2375 ...             self.fields[field[0]] = field[1]
       
  2376 >>> field_list = [('field1', CharField()), ('field2', CharField())]
       
  2377 >>> my_form = MyForm(field_list=field_list)
       
  2378 >>> print my_form
       
  2379 <tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
       
  2380 <tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
       
  2381 <tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
       
  2382 <tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
       
  2383 >>> field_list = [('field3', CharField()), ('field4', CharField())]
       
  2384 >>> my_form = MyForm(field_list=field_list)
       
  2385 >>> print my_form
       
  2386 <tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
       
  2387 <tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
       
  2388 <tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
       
  2389 <tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
       
  2390 
       
  2391 Similarly, changes to field attributes do not persist from one Form instance
       
  2392 to the next.
       
  2393 >>> class Person(Form):
       
  2394 ...     first_name = CharField(required=False)
       
  2395 ...     last_name = CharField(required=False)
       
  2396 ...     def __init__(self, names_required=False, *args, **kwargs):
       
  2397 ...         super(Person, self).__init__(*args, **kwargs)
       
  2398 ...         if names_required:
       
  2399 ...             self.fields['first_name'].required = True
       
  2400 ...             self.fields['last_name'].required = True
       
  2401 >>> f = Person(names_required=False)
       
  2402 >>> f['first_name'].field.required, f['last_name'].field.required
       
  2403 (False, False)
       
  2404 >>> f = Person(names_required=True)
       
  2405 >>> f['first_name'].field.required, f['last_name'].field.required
       
  2406 (True, True)
       
  2407 >>> f = Person(names_required=False)
       
  2408 >>> f['first_name'].field.required, f['last_name'].field.required
       
  2409 (False, False)
       
  2410 >>> class Person(Form):
       
  2411 ...     first_name = CharField(max_length=30)
       
  2412 ...     last_name = CharField(max_length=30)
       
  2413 ...     def __init__(self, name_max_length=None, *args, **kwargs):
       
  2414 ...         super(Person, self).__init__(*args, **kwargs)
       
  2415 ...         if name_max_length:
       
  2416 ...             self.fields['first_name'].max_length = name_max_length
       
  2417 ...             self.fields['last_name'].max_length = name_max_length
       
  2418 >>> f = Person(name_max_length=None)
       
  2419 >>> f['first_name'].field.max_length, f['last_name'].field.max_length
       
  2420 (30, 30)
       
  2421 >>> f = Person(name_max_length=20)
       
  2422 >>> f['first_name'].field.max_length, f['last_name'].field.max_length
       
  2423 (20, 20)
       
  2424 >>> f = Person(name_max_length=None)
       
  2425 >>> f['first_name'].field.max_length, f['last_name'].field.max_length
       
  2426 (30, 30)
       
  2427 
       
  2428 HiddenInput widgets are displayed differently in the as_table(), as_ul()
       
  2429 and as_p() output of a Form -- their verbose names are not displayed, and a
       
  2430 separate row is not displayed. They're displayed in the last row of the
       
  2431 form, directly after that row's form element.
       
  2432 >>> class Person(Form):
       
  2433 ...     first_name = CharField()
       
  2434 ...     last_name = CharField()
       
  2435 ...     hidden_text = CharField(widget=HiddenInput)
       
  2436 ...     birthday = DateField()
       
  2437 >>> p = Person(auto_id=False)
       
  2438 >>> print p
       
  2439 <tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
       
  2440 <tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
       
  2441 <tr><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr>
       
  2442 >>> print p.as_ul()
       
  2443 <li>First name: <input type="text" name="first_name" /></li>
       
  2444 <li>Last name: <input type="text" name="last_name" /></li>
       
  2445 <li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li>
       
  2446 >>> print p.as_p()
       
  2447 <p>First name: <input type="text" name="first_name" /></p>
       
  2448 <p>Last name: <input type="text" name="last_name" /></p>
       
  2449 <p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p>
       
  2450 
       
  2451 With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label.
       
  2452 >>> p = Person(auto_id='id_%s')
       
  2453 >>> print p
       
  2454 <tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
       
  2455 <tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
       
  2456 <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>
       
  2457 >>> print p.as_ul()
       
  2458 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
       
  2459 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
       
  2460 <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>
       
  2461 >>> print p.as_p()
       
  2462 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
       
  2463 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
       
  2464 <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>
       
  2465 
       
  2466 If a field with a HiddenInput has errors, the as_table() and as_ul() output
       
  2467 will include the error message(s) with the text "(Hidden field [fieldname]) "
       
  2468 prepended. This message is displayed at the top of the output, regardless of
       
  2469 its field's order in the form.
       
  2470 >>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
       
  2471 >>> print p
       
  2472 <tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr>
       
  2473 <tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
       
  2474 <tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
       
  2475 <tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>
       
  2476 >>> print p.as_ul()
       
  2477 <li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li>
       
  2478 <li>First name: <input type="text" name="first_name" value="John" /></li>
       
  2479 <li>Last name: <input type="text" name="last_name" value="Lennon" /></li>
       
  2480 <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li>
       
  2481 >>> print p.as_p()
       
  2482 <p><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></p>
       
  2483 <p>First name: <input type="text" name="first_name" value="John" /></p>
       
  2484 <p>Last name: <input type="text" name="last_name" value="Lennon" /></p>
       
  2485 <p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p>
       
  2486 
       
  2487 A corner case: It's possible for a form to have only HiddenInputs.
       
  2488 >>> class TestForm(Form):
       
  2489 ...     foo = CharField(widget=HiddenInput)
       
  2490 ...     bar = CharField(widget=HiddenInput)
       
  2491 >>> p = TestForm(auto_id=False)
       
  2492 >>> print p.as_table()
       
  2493 <input type="hidden" name="foo" /><input type="hidden" name="bar" />
       
  2494 >>> print p.as_ul()
       
  2495 <input type="hidden" name="foo" /><input type="hidden" name="bar" />
       
  2496 >>> print p.as_p()
       
  2497 <input type="hidden" name="foo" /><input type="hidden" name="bar" />
       
  2498 
       
  2499 A Form's fields are displayed in the same order in which they were defined.
       
  2500 >>> class TestForm(Form):
       
  2501 ...     field1 = CharField()
       
  2502 ...     field2 = CharField()
       
  2503 ...     field3 = CharField()
       
  2504 ...     field4 = CharField()
       
  2505 ...     field5 = CharField()
       
  2506 ...     field6 = CharField()
       
  2507 ...     field7 = CharField()
       
  2508 ...     field8 = CharField()
       
  2509 ...     field9 = CharField()
       
  2510 ...     field10 = CharField()
       
  2511 ...     field11 = CharField()
       
  2512 ...     field12 = CharField()
       
  2513 ...     field13 = CharField()
       
  2514 ...     field14 = CharField()
       
  2515 >>> p = TestForm(auto_id=False)
       
  2516 >>> print p
       
  2517 <tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
       
  2518 <tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
       
  2519 <tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
       
  2520 <tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
       
  2521 <tr><th>Field5:</th><td><input type="text" name="field5" /></td></tr>
       
  2522 <tr><th>Field6:</th><td><input type="text" name="field6" /></td></tr>
       
  2523 <tr><th>Field7:</th><td><input type="text" name="field7" /></td></tr>
       
  2524 <tr><th>Field8:</th><td><input type="text" name="field8" /></td></tr>
       
  2525 <tr><th>Field9:</th><td><input type="text" name="field9" /></td></tr>
       
  2526 <tr><th>Field10:</th><td><input type="text" name="field10" /></td></tr>
       
  2527 <tr><th>Field11:</th><td><input type="text" name="field11" /></td></tr>
       
  2528 <tr><th>Field12:</th><td><input type="text" name="field12" /></td></tr>
       
  2529 <tr><th>Field13:</th><td><input type="text" name="field13" /></td></tr>
       
  2530 <tr><th>Field14:</th><td><input type="text" name="field14" /></td></tr>
       
  2531 
       
  2532 Some Field classes have an effect on the HTML attributes of their associated
       
  2533 Widget. If you set max_length in a CharField and its associated widget is
       
  2534 either a TextInput or PasswordInput, then the widget's rendered HTML will
       
  2535 include the "maxlength" attribute.
       
  2536 >>> class UserRegistration(Form):
       
  2537 ...    username = CharField(max_length=10)                   # uses TextInput by default
       
  2538 ...    password = CharField(max_length=10, widget=PasswordInput)
       
  2539 ...    realname = CharField(max_length=10, widget=TextInput) # redundantly define widget, just to test
       
  2540 ...    address = CharField()                                 # no max_length defined here
       
  2541 >>> p = UserRegistration(auto_id=False)
       
  2542 >>> print p.as_ul()
       
  2543 <li>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2544 <li>Password: <input type="password" name="password" maxlength="10" /></li>
       
  2545 <li>Realname: <input type="text" name="realname" maxlength="10" /></li>
       
  2546 <li>Address: <input type="text" name="address" /></li>
       
  2547 
       
  2548 If you specify a custom "attrs" that includes the "maxlength" attribute,
       
  2549 the Field's max_length attribute will override whatever "maxlength" you specify
       
  2550 in "attrs".
       
  2551 >>> class UserRegistration(Form):
       
  2552 ...    username = CharField(max_length=10, widget=TextInput(attrs={'maxlength': 20}))
       
  2553 ...    password = CharField(max_length=10, widget=PasswordInput)
       
  2554 >>> p = UserRegistration(auto_id=False)
       
  2555 >>> print p.as_ul()
       
  2556 <li>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2557 <li>Password: <input type="password" name="password" maxlength="10" /></li>
       
  2558 
       
  2559 # Specifying labels ###########################################################
       
  2560 
       
  2561 You can specify the label for a field by using the 'label' argument to a Field
       
  2562 class. If you don't specify 'label', Django will use the field name with
       
  2563 underscores converted to spaces, and the initial letter capitalized.
       
  2564 >>> class UserRegistration(Form):
       
  2565 ...    username = CharField(max_length=10, label='Your username')
       
  2566 ...    password1 = CharField(widget=PasswordInput)
       
  2567 ...    password2 = CharField(widget=PasswordInput, label='Password (again)')
       
  2568 >>> p = UserRegistration(auto_id=False)
       
  2569 >>> print p.as_ul()
       
  2570 <li>Your username: <input type="text" name="username" maxlength="10" /></li>
       
  2571 <li>Password1: <input type="password" name="password1" /></li>
       
  2572 <li>Password (again): <input type="password" name="password2" /></li>
       
  2573 
       
  2574 A label can be a Unicode object or a bytestring with special characters.
       
  2575 >>> class UserRegistration(Form):
       
  2576 ...    username = CharField(max_length=10, label='ŠĐĆŽćžšđ')
       
  2577 ...    password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
       
  2578 >>> p = UserRegistration(auto_id=False)
       
  2579 >>> p.as_ul()
       
  2580 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>'
       
  2581 
       
  2582 If a label is set to the empty string for a field, that field won't get a label.
       
  2583 >>> class UserRegistration(Form):
       
  2584 ...    username = CharField(max_length=10, label='')
       
  2585 ...    password = CharField(widget=PasswordInput)
       
  2586 >>> p = UserRegistration(auto_id=False)
       
  2587 >>> print p.as_ul()
       
  2588 <li> <input type="text" name="username" maxlength="10" /></li>
       
  2589 <li>Password: <input type="password" name="password" /></li>
       
  2590 >>> p = UserRegistration(auto_id='id_%s')
       
  2591 >>> print p.as_ul()
       
  2592 <li> <input id="id_username" type="text" name="username" maxlength="10" /></li>
       
  2593 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
       
  2594 
       
  2595 If label is None, Django will auto-create the label from the field name. This
       
  2596 is default behavior.
       
  2597 >>> class UserRegistration(Form):
       
  2598 ...    username = CharField(max_length=10, label=None)
       
  2599 ...    password = CharField(widget=PasswordInput)
       
  2600 >>> p = UserRegistration(auto_id=False)
       
  2601 >>> print p.as_ul()
       
  2602 <li>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2603 <li>Password: <input type="password" name="password" /></li>
       
  2604 >>> p = UserRegistration(auto_id='id_%s')
       
  2605 >>> print p.as_ul()
       
  2606 <li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></li>
       
  2607 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
       
  2608 
       
  2609 # Initial data ################################################################
       
  2610 
       
  2611 You can specify initial data for a field by using the 'initial' argument to a
       
  2612 Field class. This initial data is displayed when a Form is rendered with *no*
       
  2613 data. It is not displayed when a Form is rendered with any data (including an
       
  2614 empty dictionary). Also, the initial value is *not* used if data for a
       
  2615 particular required field isn't provided.
       
  2616 >>> class UserRegistration(Form):
       
  2617 ...    username = CharField(max_length=10, initial='django')
       
  2618 ...    password = CharField(widget=PasswordInput)
       
  2619 
       
  2620 Here, we're not submitting any data, so the initial value will be displayed.
       
  2621 >>> p = UserRegistration(auto_id=False)
       
  2622 >>> print p.as_ul()
       
  2623 <li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
       
  2624 <li>Password: <input type="password" name="password" /></li>
       
  2625 
       
  2626 Here, we're submitting data, so the initial value will *not* be displayed.
       
  2627 >>> p = UserRegistration({}, auto_id=False)
       
  2628 >>> print p.as_ul()
       
  2629 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2630 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2631 >>> p = UserRegistration({'username': u''}, auto_id=False)
       
  2632 >>> print p.as_ul()
       
  2633 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2634 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2635 >>> p = UserRegistration({'username': u'foo'}, auto_id=False)
       
  2636 >>> print p.as_ul()
       
  2637 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
       
  2638 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2639 
       
  2640 An 'initial' value is *not* used as a fallback if data is not provided. In this
       
  2641 example, we don't provide a value for 'username', and the form raises a
       
  2642 validation error rather than using the initial value for 'username'.
       
  2643 >>> p = UserRegistration({'password': 'secret'})
       
  2644 >>> p.errors
       
  2645 {'username': [u'This field is required.']}
       
  2646 >>> p.is_valid()
       
  2647 False
       
  2648 
       
  2649 # Dynamic initial data ########################################################
       
  2650 
       
  2651 The previous technique dealt with "hard-coded" initial data, but it's also
       
  2652 possible to specify initial data after you've already created the Form class
       
  2653 (i.e., at runtime). Use the 'initial' parameter to the Form constructor. This
       
  2654 should be a dictionary containing initial values for one or more fields in the
       
  2655 form, keyed by field name.
       
  2656 
       
  2657 >>> class UserRegistration(Form):
       
  2658 ...    username = CharField(max_length=10)
       
  2659 ...    password = CharField(widget=PasswordInput)
       
  2660 
       
  2661 Here, we're not submitting any data, so the initial value will be displayed.
       
  2662 >>> p = UserRegistration(initial={'username': 'django'}, auto_id=False)
       
  2663 >>> print p.as_ul()
       
  2664 <li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
       
  2665 <li>Password: <input type="password" name="password" /></li>
       
  2666 >>> p = UserRegistration(initial={'username': 'stephane'}, auto_id=False)
       
  2667 >>> print p.as_ul()
       
  2668 <li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
       
  2669 <li>Password: <input type="password" name="password" /></li>
       
  2670 
       
  2671 The 'initial' parameter is meaningless if you pass data.
       
  2672 >>> p = UserRegistration({}, initial={'username': 'django'}, auto_id=False)
       
  2673 >>> print p.as_ul()
       
  2674 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2675 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2676 >>> p = UserRegistration({'username': u''}, initial={'username': 'django'}, auto_id=False)
       
  2677 >>> print p.as_ul()
       
  2678 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
       
  2679 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2680 >>> p = UserRegistration({'username': u'foo'}, initial={'username': 'django'}, auto_id=False)
       
  2681 >>> print p.as_ul()
       
  2682 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
       
  2683 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
       
  2684 
       
  2685 A dynamic 'initial' value is *not* used as a fallback if data is not provided.
       
  2686 In this example, we don't provide a value for 'username', and the form raises a
       
  2687 validation error rather than using the initial value for 'username'.
       
  2688 >>> p = UserRegistration({'password': 'secret'}, initial={'username': 'django'})
       
  2689 >>> p.errors
       
  2690 {'username': [u'This field is required.']}
       
  2691 >>> p.is_valid()
       
  2692 False
       
  2693 
       
  2694 If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
       
  2695 then the latter will get precedence.
       
  2696 >>> class UserRegistration(Form):
       
  2697 ...    username = CharField(max_length=10, initial='django')
       
  2698 ...    password = CharField(widget=PasswordInput)
       
  2699 >>> p = UserRegistration(initial={'username': 'babik'}, auto_id=False)
       
  2700 >>> print p.as_ul()
       
  2701 <li>Username: <input type="text" name="username" value="babik" maxlength="10" /></li>
       
  2702 <li>Password: <input type="password" name="password" /></li>
       
  2703 
       
  2704 # Help text ###################################################################
       
  2705 
       
  2706 You can specify descriptive text for a field by using the 'help_text' argument
       
  2707 to a Field class. This help text is displayed when a Form is rendered.
       
  2708 >>> class UserRegistration(Form):
       
  2709 ...    username = CharField(max_length=10, help_text='e.g., user@example.com')
       
  2710 ...    password = CharField(widget=PasswordInput, help_text='Choose wisely.')
       
  2711 >>> p = UserRegistration(auto_id=False)
       
  2712 >>> print p.as_ul()
       
  2713 <li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
       
  2714 <li>Password: <input type="password" name="password" /> Choose wisely.</li>
       
  2715 >>> print p.as_p()
       
  2716 <p>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p>
       
  2717 <p>Password: <input type="password" name="password" /> Choose wisely.</p>
       
  2718 >>> print p.as_table()
       
  2719 <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr>
       
  2720 <tr><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr>
       
  2721 
       
  2722 The help text is displayed whether or not data is provided for the form.
       
  2723 >>> p = UserRegistration({'username': u'foo'}, auto_id=False)
       
  2724 >>> print p.as_ul()
       
  2725 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li>
       
  2726 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li>
       
  2727 
       
  2728 help_text is not displayed for hidden fields. It can be used for documentation
       
  2729 purposes, though.
       
  2730 >>> class UserRegistration(Form):
       
  2731 ...    username = CharField(max_length=10, help_text='e.g., user@example.com')
       
  2732 ...    password = CharField(widget=PasswordInput)
       
  2733 ...    next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
       
  2734 >>> p = UserRegistration(auto_id=False)
       
  2735 >>> print p.as_ul()
       
  2736 <li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
       
  2737 <li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>
       
  2738 
       
  2739 Help text can include arbitrary Unicode characters.
       
  2740 >>> class UserRegistration(Form):
       
  2741 ...    username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ')
       
  2742 >>> p = UserRegistration(auto_id=False)
       
  2743 >>> p.as_ul()
       
  2744 u'<li>Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>'
       
  2745 
       
  2746 # Subclassing forms ###########################################################
       
  2747 
       
  2748 You can subclass a Form to add fields. The resulting form subclass will have
       
  2749 all of the fields of the parent Form, plus whichever fields you define in the
       
  2750 subclass.
       
  2751 >>> class Person(Form):
       
  2752 ...     first_name = CharField()
       
  2753 ...     last_name = CharField()
       
  2754 ...     birthday = DateField()
       
  2755 >>> class Musician(Person):
       
  2756 ...     instrument = CharField()
       
  2757 >>> p = Person(auto_id=False)
       
  2758 >>> print p.as_ul()
       
  2759 <li>First name: <input type="text" name="first_name" /></li>
       
  2760 <li>Last name: <input type="text" name="last_name" /></li>
       
  2761 <li>Birthday: <input type="text" name="birthday" /></li>
       
  2762 >>> m = Musician(auto_id=False)
       
  2763 >>> print m.as_ul()
       
  2764 <li>First name: <input type="text" name="first_name" /></li>
       
  2765 <li>Last name: <input type="text" name="last_name" /></li>
       
  2766 <li>Birthday: <input type="text" name="birthday" /></li>
       
  2767 <li>Instrument: <input type="text" name="instrument" /></li>
       
  2768 
       
  2769 Yes, you can subclass multiple forms. The fields are added in the order in
       
  2770 which the parent classes are listed.
       
  2771 >>> class Person(Form):
       
  2772 ...     first_name = CharField()
       
  2773 ...     last_name = CharField()
       
  2774 ...     birthday = DateField()
       
  2775 >>> class Instrument(Form):
       
  2776 ...     instrument = CharField()
       
  2777 >>> class Beatle(Person, Instrument):
       
  2778 ...     haircut_type = CharField()
       
  2779 >>> b = Beatle(auto_id=False)
       
  2780 >>> print b.as_ul()
       
  2781 <li>First name: <input type="text" name="first_name" /></li>
       
  2782 <li>Last name: <input type="text" name="last_name" /></li>
       
  2783 <li>Birthday: <input type="text" name="birthday" /></li>
       
  2784 <li>Instrument: <input type="text" name="instrument" /></li>
       
  2785 <li>Haircut type: <input type="text" name="haircut_type" /></li>
       
  2786 
       
  2787 # Forms with prefixes #########################################################
       
  2788 
       
  2789 Sometimes it's necessary to have multiple forms display on the same HTML page,
       
  2790 or multiple copies of the same form. We can accomplish this with form prefixes.
       
  2791 Pass the keyword argument 'prefix' to the Form constructor to use this feature.
       
  2792 This value will be prepended to each HTML form field name. One way to think
       
  2793 about this is "namespaces for HTML forms". Notice that in the data argument,
       
  2794 each field's key has the prefix, in this case 'person1', prepended to the
       
  2795 actual field name.
       
  2796 >>> class Person(Form):
       
  2797 ...     first_name = CharField()
       
  2798 ...     last_name = CharField()
       
  2799 ...     birthday = DateField()
       
  2800 >>> data = {
       
  2801 ...     'person1-first_name': u'John',
       
  2802 ...     'person1-last_name': u'Lennon',
       
  2803 ...     'person1-birthday': u'1940-10-9'
       
  2804 ... }
       
  2805 >>> p = Person(data, prefix='person1')
       
  2806 >>> print p.as_ul()
       
  2807 <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>
       
  2808 <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>
       
  2809 <li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li>
       
  2810 >>> print p['first_name']
       
  2811 <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" />
       
  2812 >>> print p['last_name']
       
  2813 <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" />
       
  2814 >>> print p['birthday']
       
  2815 <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" />
       
  2816 >>> p.errors
       
  2817 {}
       
  2818 >>> p.is_valid()
       
  2819 True
       
  2820 >>> p.clean_data
       
  2821 {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
       
  2822 
       
  2823 Let's try submitting some bad data to make sure form.errors and field.errors
       
  2824 work as expected.
       
  2825 >>> data = {
       
  2826 ...     'person1-first_name': u'',
       
  2827 ...     'person1-last_name': u'',
       
  2828 ...     'person1-birthday': u''
       
  2829 ... }
       
  2830 >>> p = Person(data, prefix='person1')
       
  2831 >>> p.errors
       
  2832 {'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
       
  2833 >>> p['first_name'].errors
       
  2834 [u'This field is required.']
       
  2835 >>> p['person1-first_name'].errors
       
  2836 Traceback (most recent call last):
       
  2837 ...
       
  2838 KeyError: "Key 'person1-first_name' not found in Form"
       
  2839 
       
  2840 In this example, the data doesn't have a prefix, but the form requires it, so
       
  2841 the form doesn't "see" the fields.
       
  2842 >>> data = {
       
  2843 ...     'first_name': u'John',
       
  2844 ...     'last_name': u'Lennon',
       
  2845 ...     'birthday': u'1940-10-9'
       
  2846 ... }
       
  2847 >>> p = Person(data, prefix='person1')
       
  2848 >>> p.errors
       
  2849 {'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
       
  2850 
       
  2851 With prefixes, a single data dictionary can hold data for multiple instances
       
  2852 of the same form.
       
  2853 >>> data = {
       
  2854 ...     'person1-first_name': u'John',
       
  2855 ...     'person1-last_name': u'Lennon',
       
  2856 ...     'person1-birthday': u'1940-10-9',
       
  2857 ...     'person2-first_name': u'Jim',
       
  2858 ...     'person2-last_name': u'Morrison',
       
  2859 ...     'person2-birthday': u'1943-12-8'
       
  2860 ... }
       
  2861 >>> p1 = Person(data, prefix='person1')
       
  2862 >>> p1.is_valid()
       
  2863 True
       
  2864 >>> p1.clean_data
       
  2865 {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
       
  2866 >>> p2 = Person(data, prefix='person2')
       
  2867 >>> p2.is_valid()
       
  2868 True
       
  2869 >>> p2.clean_data
       
  2870 {'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)}
       
  2871 
       
  2872 By default, forms append a hyphen between the prefix and the field name, but a
       
  2873 form can alter that behavior by implementing the add_prefix() method. This
       
  2874 method takes a field name and returns the prefixed field, according to
       
  2875 self.prefix.
       
  2876 >>> class Person(Form):
       
  2877 ...     first_name = CharField()
       
  2878 ...     last_name = CharField()
       
  2879 ...     birthday = DateField()
       
  2880 ...     def add_prefix(self, field_name):
       
  2881 ...         return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name
       
  2882 >>> p = Person(prefix='foo')
       
  2883 >>> print p.as_ul()
       
  2884 <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>
       
  2885 <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>
       
  2886 <li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li>
       
  2887 >>> data = {
       
  2888 ...     'foo-prefix-first_name': u'John',
       
  2889 ...     'foo-prefix-last_name': u'Lennon',
       
  2890 ...     'foo-prefix-birthday': u'1940-10-9'
       
  2891 ... }
       
  2892 >>> p = Person(data, prefix='foo')
       
  2893 >>> p.is_valid()
       
  2894 True
       
  2895 >>> p.clean_data
       
  2896 {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
       
  2897 
       
  2898 # Forms with NullBooleanFields ################################################
       
  2899 
       
  2900 NullBooleanField is a bit of a special case because its presentation (widget)
       
  2901 is different than its data. This is handled transparently, though.
       
  2902 
       
  2903 >>> class Person(Form):
       
  2904 ...     name = CharField()
       
  2905 ...     is_cool = NullBooleanField()
       
  2906 >>> p = Person({'name': u'Joe'}, auto_id=False)
       
  2907 >>> print p['is_cool']
       
  2908 <select name="is_cool">
       
  2909 <option value="1" selected="selected">Unknown</option>
       
  2910 <option value="2">Yes</option>
       
  2911 <option value="3">No</option>
       
  2912 </select>
       
  2913 >>> p = Person({'name': u'Joe', 'is_cool': u'1'}, auto_id=False)
       
  2914 >>> print p['is_cool']
       
  2915 <select name="is_cool">
       
  2916 <option value="1" selected="selected">Unknown</option>
       
  2917 <option value="2">Yes</option>
       
  2918 <option value="3">No</option>
       
  2919 </select>
       
  2920 >>> p = Person({'name': u'Joe', 'is_cool': u'2'}, auto_id=False)
       
  2921 >>> print p['is_cool']
       
  2922 <select name="is_cool">
       
  2923 <option value="1">Unknown</option>
       
  2924 <option value="2" selected="selected">Yes</option>
       
  2925 <option value="3">No</option>
       
  2926 </select>
       
  2927 >>> p = Person({'name': u'Joe', 'is_cool': u'3'}, auto_id=False)
       
  2928 >>> print p['is_cool']
       
  2929 <select name="is_cool">
       
  2930 <option value="1">Unknown</option>
       
  2931 <option value="2">Yes</option>
       
  2932 <option value="3" selected="selected">No</option>
       
  2933 </select>
       
  2934 >>> p = Person({'name': u'Joe', 'is_cool': True}, auto_id=False)
       
  2935 >>> print p['is_cool']
       
  2936 <select name="is_cool">
       
  2937 <option value="1">Unknown</option>
       
  2938 <option value="2" selected="selected">Yes</option>
       
  2939 <option value="3">No</option>
       
  2940 </select>
       
  2941 >>> p = Person({'name': u'Joe', 'is_cool': False}, auto_id=False)
       
  2942 >>> print p['is_cool']
       
  2943 <select name="is_cool">
       
  2944 <option value="1">Unknown</option>
       
  2945 <option value="2">Yes</option>
       
  2946 <option value="3" selected="selected">No</option>
       
  2947 </select>
       
  2948 
       
  2949 # Basic form processing in a view #############################################
       
  2950 
       
  2951 >>> from django.template import Template, Context
       
  2952 >>> class UserRegistration(Form):
       
  2953 ...    username = CharField(max_length=10)
       
  2954 ...    password1 = CharField(widget=PasswordInput)
       
  2955 ...    password2 = CharField(widget=PasswordInput)
       
  2956 ...    def clean(self):
       
  2957 ...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
       
  2958 ...            raise ValidationError(u'Please make sure your passwords match.')
       
  2959 ...        return self.clean_data
       
  2960 >>> def my_function(method, post_data):
       
  2961 ...     if method == 'POST':
       
  2962 ...         form = UserRegistration(post_data, auto_id=False)
       
  2963 ...     else:
       
  2964 ...         form = UserRegistration(auto_id=False)
       
  2965 ...     if form.is_valid():
       
  2966 ...         return 'VALID: %r' % form.clean_data
       
  2967 ...     t = Template('<form action="" method="post">\n<table>\n{{ form }}\n</table>\n<input type="submit" />\n</form>')
       
  2968 ...     return t.render(Context({'form': form}))
       
  2969 
       
  2970 Case 1: GET (an empty form, with no errors).
       
  2971 >>> print my_function('GET', {})
       
  2972 <form action="" method="post">
       
  2973 <table>
       
  2974 <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr>
       
  2975 <tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
       
  2976 <tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
       
  2977 </table>
       
  2978 <input type="submit" />
       
  2979 </form>
       
  2980 
       
  2981 Case 2: POST with erroneous data (a redisplayed form, with errors).
       
  2982 >>> print my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'})
       
  2983 <form action="" method="post">
       
  2984 <table>
       
  2985 <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
       
  2986 <tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters.</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
       
  2987 <tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
       
  2988 <tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
       
  2989 </table>
       
  2990 <input type="submit" />
       
  2991 </form>
       
  2992 
       
  2993 Case 3: POST with valid data (the success message).
       
  2994 >>> print my_function('POST', {'username': 'adrian', 'password1': 'secret', 'password2': 'secret'})
       
  2995 VALID: {'username': u'adrian', 'password1': u'secret', 'password2': u'secret'}
       
  2996 
       
  2997 # Some ideas for using templates with forms ###################################
       
  2998 
       
  2999 >>> class UserRegistration(Form):
       
  3000 ...    username = CharField(max_length=10, help_text="Good luck picking a username that doesn't already exist.")
       
  3001 ...    password1 = CharField(widget=PasswordInput)
       
  3002 ...    password2 = CharField(widget=PasswordInput)
       
  3003 ...    def clean(self):
       
  3004 ...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
       
  3005 ...            raise ValidationError(u'Please make sure your passwords match.')
       
  3006 ...        return self.clean_data
       
  3007 
       
  3008 You have full flexibility in displaying form fields in a template. Just pass a
       
  3009 Form instance to the template, and use "dot" access to refer to individual
       
  3010 fields. Note, however, that this flexibility comes with the responsibility of
       
  3011 displaying all the errors, including any that might not be associated with a
       
  3012 particular field.
       
  3013 >>> t = Template('''<form action="">
       
  3014 ... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
       
  3015 ... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
       
  3016 ... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
       
  3017 ... <input type="submit" />
       
  3018 ... </form>''')
       
  3019 >>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
       
  3020 <form action="">
       
  3021 <p><label>Your username: <input type="text" name="username" maxlength="10" /></label></p>
       
  3022 <p><label>Password: <input type="password" name="password1" /></label></p>
       
  3023 <p><label>Password (again): <input type="password" name="password2" /></label></p>
       
  3024 <input type="submit" />
       
  3025 </form>
       
  3026 >>> print t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)}))
       
  3027 <form action="">
       
  3028 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
       
  3029 <ul class="errorlist"><li>This field is required.</li></ul><p><label>Password: <input type="password" name="password1" /></label></p>
       
  3030 <ul class="errorlist"><li>This field is required.</li></ul><p><label>Password (again): <input type="password" name="password2" /></label></p>
       
  3031 <input type="submit" />
       
  3032 </form>
       
  3033 
       
  3034 Use form.[field].label to output a field's label. You can specify the label for
       
  3035 a field by using the 'label' argument to a Field class. If you don't specify
       
  3036 'label', Django will use the field name with underscores converted to spaces,
       
  3037 and the initial letter capitalized.
       
  3038 >>> t = Template('''<form action="">
       
  3039 ... <p><label>{{ form.username.label }}: {{ form.username }}</label></p>
       
  3040 ... <p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>
       
  3041 ... <p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>
       
  3042 ... <input type="submit" />
       
  3043 ... </form>''')
       
  3044 >>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
       
  3045 <form action="">
       
  3046 <p><label>Username: <input type="text" name="username" maxlength="10" /></label></p>
       
  3047 <p><label>Password1: <input type="password" name="password1" /></label></p>
       
  3048 <p><label>Password2: <input type="password" name="password2" /></label></p>
       
  3049 <input type="submit" />
       
  3050 </form>
       
  3051 
       
  3052 User form.[field].label_tag to output a field's label with a <label> tag
       
  3053 wrapped around it, but *only* if the given field has an "id" attribute.
       
  3054 Recall from above that passing the "auto_id" argument to a Form gives each
       
  3055 field an "id" attribute.
       
  3056 >>> t = Template('''<form action="">
       
  3057 ... <p>{{ form.username.label_tag }}: {{ form.username }}</p>
       
  3058 ... <p>{{ form.password1.label_tag }}: {{ form.password1 }}</p>
       
  3059 ... <p>{{ form.password2.label_tag }}: {{ form.password2 }}</p>
       
  3060 ... <input type="submit" />
       
  3061 ... </form>''')
       
  3062 >>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
       
  3063 <form action="">
       
  3064 <p>Username: <input type="text" name="username" maxlength="10" /></p>
       
  3065 <p>Password1: <input type="password" name="password1" /></p>
       
  3066 <p>Password2: <input type="password" name="password2" /></p>
       
  3067 <input type="submit" />
       
  3068 </form>
       
  3069 >>> print t.render(Context({'form': UserRegistration(auto_id='id_%s')}))
       
  3070 <form action="">
       
  3071 <p><label for="id_username">Username</label>: <input id="id_username" type="text" name="username" maxlength="10" /></p>
       
  3072 <p><label for="id_password1">Password1</label>: <input type="password" name="password1" id="id_password1" /></p>
       
  3073 <p><label for="id_password2">Password2</label>: <input type="password" name="password2" id="id_password2" /></p>
       
  3074 <input type="submit" />
       
  3075 </form>
       
  3076 
       
  3077 User form.[field].help_text to output a field's help text. If the given field
       
  3078 does not have help text, nothing will be output.
       
  3079 >>> t = Template('''<form action="">
       
  3080 ... <p>{{ form.username.label_tag }}: {{ form.username }}<br />{{ form.username.help_text }}</p>
       
  3081 ... <p>{{ form.password1.label_tag }}: {{ form.password1 }}</p>
       
  3082 ... <p>{{ form.password2.label_tag }}: {{ form.password2 }}</p>
       
  3083 ... <input type="submit" />
       
  3084 ... </form>''')
       
  3085 >>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
       
  3086 <form action="">
       
  3087 <p>Username: <input type="text" name="username" maxlength="10" /><br />Good luck picking a username that doesn't already exist.</p>
       
  3088 <p>Password1: <input type="password" name="password1" /></p>
       
  3089 <p>Password2: <input type="password" name="password2" /></p>
       
  3090 <input type="submit" />
       
  3091 </form>
       
  3092 >>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)}))
       
  3093 ''
       
  3094 
       
  3095 The label_tag() method takes an optional attrs argument: a dictionary of HTML
       
  3096 attributes to add to the <label> tag.
       
  3097 >>> f = UserRegistration(auto_id='id_%s')
       
  3098 >>> for bf in f:
       
  3099 ...     print bf.label_tag(attrs={'class': 'pretty'})
       
  3100 <label for="id_username" class="pretty">Username</label>
       
  3101 <label for="id_password1" class="pretty">Password1</label>
       
  3102 <label for="id_password2" class="pretty">Password2</label>
       
  3103 
       
  3104 To display the errors that aren't associated with a particular field -- e.g.,
       
  3105 the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
       
  3106 template. If used on its own, it is displayed as a <ul> (or an empty string, if
       
  3107 the list of errors is empty). You can also use it in {% if %} statements.
       
  3108 >>> t = Template('''<form action="">
       
  3109 ... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
       
  3110 ... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
       
  3111 ... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
       
  3112 ... <input type="submit" />
       
  3113 ... </form>''')
       
  3114 >>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
       
  3115 <form action="">
       
  3116 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
       
  3117 <p><label>Password: <input type="password" name="password1" value="foo" /></label></p>
       
  3118 <p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p>
       
  3119 <input type="submit" />
       
  3120 </form>
       
  3121 >>> t = Template('''<form action="">
       
  3122 ... {{ form.non_field_errors }}
       
  3123 ... {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
       
  3124 ... {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
       
  3125 ... {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
       
  3126 ... <input type="submit" />
       
  3127 ... </form>''')
       
  3128 >>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
       
  3129 <form action="">
       
  3130 <ul class="errorlist"><li>Please make sure your passwords match.</li></ul>
       
  3131 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
       
  3132 <p><label>Password: <input type="password" name="password1" value="foo" /></label></p>
       
  3133 <p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p>
       
  3134 <input type="submit" />
       
  3135 </form>
       
  3136 
       
  3137 ###############
       
  3138 # Extra stuff #
       
  3139 ###############
       
  3140 
       
  3141 The newforms library comes with some extra, higher-level Field and Widget
       
  3142 classes that demonstrate some of the library's abilities.
       
  3143 
       
  3144 # SelectDateWidget ############################################################
       
  3145 
       
  3146 >>> from django.newforms.extras import SelectDateWidget
       
  3147 >>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
       
  3148 >>> print w.render('mydate', '')
       
  3149 <select name="mydate_month">
       
  3150 <option value="1">January</option>
       
  3151 <option value="2">February</option>
       
  3152 <option value="3">March</option>
       
  3153 <option value="4">April</option>
       
  3154 <option value="5">May</option>
       
  3155 <option value="6">June</option>
       
  3156 <option value="7">July</option>
       
  3157 <option value="8">August</option>
       
  3158 <option value="9">September</option>
       
  3159 <option value="10">October</option>
       
  3160 <option value="11">November</option>
       
  3161 <option value="12">December</option>
       
  3162 </select>
       
  3163 <select name="mydate_day">
       
  3164 <option value="1">1</option>
       
  3165 <option value="2">2</option>
       
  3166 <option value="3">3</option>
       
  3167 <option value="4">4</option>
       
  3168 <option value="5">5</option>
       
  3169 <option value="6">6</option>
       
  3170 <option value="7">7</option>
       
  3171 <option value="8">8</option>
       
  3172 <option value="9">9</option>
       
  3173 <option value="10">10</option>
       
  3174 <option value="11">11</option>
       
  3175 <option value="12">12</option>
       
  3176 <option value="13">13</option>
       
  3177 <option value="14">14</option>
       
  3178 <option value="15">15</option>
       
  3179 <option value="16">16</option>
       
  3180 <option value="17">17</option>
       
  3181 <option value="18">18</option>
       
  3182 <option value="19">19</option>
       
  3183 <option value="20">20</option>
       
  3184 <option value="21">21</option>
       
  3185 <option value="22">22</option>
       
  3186 <option value="23">23</option>
       
  3187 <option value="24">24</option>
       
  3188 <option value="25">25</option>
       
  3189 <option value="26">26</option>
       
  3190 <option value="27">27</option>
       
  3191 <option value="28">28</option>
       
  3192 <option value="29">29</option>
       
  3193 <option value="30">30</option>
       
  3194 <option value="31">31</option>
       
  3195 </select>
       
  3196 <select name="mydate_year">
       
  3197 <option value="2007">2007</option>
       
  3198 <option value="2008">2008</option>
       
  3199 <option value="2009">2009</option>
       
  3200 <option value="2010">2010</option>
       
  3201 <option value="2011">2011</option>
       
  3202 <option value="2012">2012</option>
       
  3203 <option value="2013">2013</option>
       
  3204 <option value="2014">2014</option>
       
  3205 <option value="2015">2015</option>
       
  3206 <option value="2016">2016</option>
       
  3207 </select>
       
  3208 >>> w.render('mydate', None) == w.render('mydate', '')
       
  3209 True
       
  3210 >>> print w.render('mydate', '2010-04-15')
       
  3211 <select name="mydate_month">
       
  3212 <option value="1">January</option>
       
  3213 <option value="2">February</option>
       
  3214 <option value="3">March</option>
       
  3215 <option value="4" selected="selected">April</option>
       
  3216 <option value="5">May</option>
       
  3217 <option value="6">June</option>
       
  3218 <option value="7">July</option>
       
  3219 <option value="8">August</option>
       
  3220 <option value="9">September</option>
       
  3221 <option value="10">October</option>
       
  3222 <option value="11">November</option>
       
  3223 <option value="12">December</option>
       
  3224 </select>
       
  3225 <select name="mydate_day">
       
  3226 <option value="1">1</option>
       
  3227 <option value="2">2</option>
       
  3228 <option value="3">3</option>
       
  3229 <option value="4">4</option>
       
  3230 <option value="5">5</option>
       
  3231 <option value="6">6</option>
       
  3232 <option value="7">7</option>
       
  3233 <option value="8">8</option>
       
  3234 <option value="9">9</option>
       
  3235 <option value="10">10</option>
       
  3236 <option value="11">11</option>
       
  3237 <option value="12">12</option>
       
  3238 <option value="13">13</option>
       
  3239 <option value="14">14</option>
       
  3240 <option value="15" selected="selected">15</option>
       
  3241 <option value="16">16</option>
       
  3242 <option value="17">17</option>
       
  3243 <option value="18">18</option>
       
  3244 <option value="19">19</option>
       
  3245 <option value="20">20</option>
       
  3246 <option value="21">21</option>
       
  3247 <option value="22">22</option>
       
  3248 <option value="23">23</option>
       
  3249 <option value="24">24</option>
       
  3250 <option value="25">25</option>
       
  3251 <option value="26">26</option>
       
  3252 <option value="27">27</option>
       
  3253 <option value="28">28</option>
       
  3254 <option value="29">29</option>
       
  3255 <option value="30">30</option>
       
  3256 <option value="31">31</option>
       
  3257 </select>
       
  3258 <select name="mydate_year">
       
  3259 <option value="2007">2007</option>
       
  3260 <option value="2008">2008</option>
       
  3261 <option value="2009">2009</option>
       
  3262 <option value="2010" selected="selected">2010</option>
       
  3263 <option value="2011">2011</option>
       
  3264 <option value="2012">2012</option>
       
  3265 <option value="2013">2013</option>
       
  3266 <option value="2014">2014</option>
       
  3267 <option value="2015">2015</option>
       
  3268 <option value="2016">2016</option>
       
  3269 </select>
       
  3270 
       
  3271 # USZipCodeField ##############################################################
       
  3272 
       
  3273 USZipCodeField validates that the data is either a five-digit U.S. zip code or
       
  3274 a zip+4.
       
  3275 >>> from django.contrib.localflavor.usa.forms import USZipCodeField
       
  3276 >>> f = USZipCodeField()
       
  3277 >>> f.clean('60606')
       
  3278 u'60606'
       
  3279 >>> f.clean(60606)
       
  3280 u'60606'
       
  3281 >>> f.clean('04000')
       
  3282 u'04000'
       
  3283 >>> f.clean('4000')
       
  3284 Traceback (most recent call last):
       
  3285 ...
       
  3286 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3287 >>> f.clean('60606-1234')
       
  3288 u'60606-1234'
       
  3289 >>> f.clean('6060-1234')
       
  3290 Traceback (most recent call last):
       
  3291 ...
       
  3292 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3293 >>> f.clean('60606-')
       
  3294 Traceback (most recent call last):
       
  3295 ...
       
  3296 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3297 >>> f.clean(None)
       
  3298 Traceback (most recent call last):
       
  3299 ...
       
  3300 ValidationError: [u'This field is required.']
       
  3301 >>> f.clean('')
       
  3302 Traceback (most recent call last):
       
  3303 ...
       
  3304 ValidationError: [u'This field is required.']
       
  3305 
       
  3306 >>> f = USZipCodeField(required=False)
       
  3307 >>> f.clean('60606')
       
  3308 u'60606'
       
  3309 >>> f.clean(60606)
       
  3310 u'60606'
       
  3311 >>> f.clean('04000')
       
  3312 u'04000'
       
  3313 >>> f.clean('4000')
       
  3314 Traceback (most recent call last):
       
  3315 ...
       
  3316 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3317 >>> f.clean('60606-1234')
       
  3318 u'60606-1234'
       
  3319 >>> f.clean('6060-1234')
       
  3320 Traceback (most recent call last):
       
  3321 ...
       
  3322 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3323 >>> f.clean('60606-')
       
  3324 Traceback (most recent call last):
       
  3325 ...
       
  3326 ValidationError: [u'Enter a zip code in the format XXXXX or XXXXX-XXXX.']
       
  3327 >>> f.clean(None)
       
  3328 u''
       
  3329 >>> f.clean('')
       
  3330 u''
       
  3331 
       
  3332 # USPhoneNumberField ##########################################################
       
  3333 
       
  3334 USPhoneNumberField validates that the data is a valid U.S. phone number,
       
  3335 including the area code. It's normalized to XXX-XXX-XXXX format.
       
  3336 >>> from django.contrib.localflavor.usa.forms import USPhoneNumberField
       
  3337 >>> f = USPhoneNumberField()
       
  3338 >>> f.clean('312-555-1212')
       
  3339 u'312-555-1212'
       
  3340 >>> f.clean('3125551212')
       
  3341 u'312-555-1212'
       
  3342 >>> f.clean('312 555-1212')
       
  3343 u'312-555-1212'
       
  3344 >>> f.clean('(312) 555-1212')
       
  3345 u'312-555-1212'
       
  3346 >>> f.clean('312 555 1212')
       
  3347 u'312-555-1212'
       
  3348 >>> f.clean('312.555.1212')
       
  3349 u'312-555-1212'
       
  3350 >>> f.clean('312.555-1212')
       
  3351 u'312-555-1212'
       
  3352 >>> f.clean(' (312) 555.1212 ')
       
  3353 u'312-555-1212'
       
  3354 >>> f.clean('555-1212')
       
  3355 Traceback (most recent call last):
       
  3356 ...
       
  3357 ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
       
  3358 >>> f.clean('312-55-1212')
       
  3359 Traceback (most recent call last):
       
  3360 ...
       
  3361 ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
       
  3362 >>> f.clean(None)
       
  3363 Traceback (most recent call last):
       
  3364 ...
       
  3365 ValidationError: [u'This field is required.']
       
  3366 >>> f.clean('')
       
  3367 Traceback (most recent call last):
       
  3368 ...
       
  3369 ValidationError: [u'This field is required.']
       
  3370 
       
  3371 >>> f = USPhoneNumberField(required=False)
       
  3372 >>> f.clean('312-555-1212')
       
  3373 u'312-555-1212'
       
  3374 >>> f.clean('3125551212')
       
  3375 u'312-555-1212'
       
  3376 >>> f.clean('312 555-1212')
       
  3377 u'312-555-1212'
       
  3378 >>> f.clean('(312) 555-1212')
       
  3379 u'312-555-1212'
       
  3380 >>> f.clean('312 555 1212')
       
  3381 u'312-555-1212'
       
  3382 >>> f.clean('312.555.1212')
       
  3383 u'312-555-1212'
       
  3384 >>> f.clean('312.555-1212')
       
  3385 u'312-555-1212'
       
  3386 >>> f.clean(' (312) 555.1212 ')
       
  3387 u'312-555-1212'
       
  3388 >>> f.clean('555-1212')
       
  3389 Traceback (most recent call last):
       
  3390 ...
       
  3391 ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
       
  3392 >>> f.clean('312-55-1212')
       
  3393 Traceback (most recent call last):
       
  3394 ...
       
  3395 ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
       
  3396 >>> f.clean(None)
       
  3397 u''
       
  3398 >>> f.clean('')
       
  3399 u''
       
  3400 
       
  3401 # USStateField ################################################################
       
  3402 
       
  3403 USStateField validates that the data is either an abbreviation or name of a
       
  3404 U.S. state.
       
  3405 >>> from django.contrib.localflavor.usa.forms import USStateField
       
  3406 >>> f = USStateField()
       
  3407 >>> f.clean('il')
       
  3408 u'IL'
       
  3409 >>> f.clean('IL')
       
  3410 u'IL'
       
  3411 >>> f.clean('illinois')
       
  3412 u'IL'
       
  3413 >>> f.clean('  illinois ')
       
  3414 u'IL'
       
  3415 >>> f.clean(60606)
       
  3416 Traceback (most recent call last):
       
  3417 ...
       
  3418 ValidationError: [u'Enter a U.S. state or territory.']
       
  3419 >>> f.clean(None)
       
  3420 Traceback (most recent call last):
       
  3421 ...
       
  3422 ValidationError: [u'This field is required.']
       
  3423 >>> f.clean('')
       
  3424 Traceback (most recent call last):
       
  3425 ...
       
  3426 ValidationError: [u'This field is required.']
       
  3427 
       
  3428 >>> f = USStateField(required=False)
       
  3429 >>> f.clean('il')
       
  3430 u'IL'
       
  3431 >>> f.clean('IL')
       
  3432 u'IL'
       
  3433 >>> f.clean('illinois')
       
  3434 u'IL'
       
  3435 >>> f.clean('  illinois ')
       
  3436 u'IL'
       
  3437 >>> f.clean(60606)
       
  3438 Traceback (most recent call last):
       
  3439 ...
       
  3440 ValidationError: [u'Enter a U.S. state or territory.']
       
  3441 >>> f.clean(None)
       
  3442 u''
       
  3443 >>> f.clean('')
       
  3444 u''
       
  3445 
       
  3446 # USStateSelect ###############################################################
       
  3447 
       
  3448 USStateSelect is a Select widget that uses a list of U.S. states/territories
       
  3449 as its choices.
       
  3450 >>> from django.contrib.localflavor.usa.forms import USStateSelect
       
  3451 >>> w = USStateSelect()
       
  3452 >>> print w.render('state', 'IL')
       
  3453 <select name="state">
       
  3454 <option value="AL">Alabama</option>
       
  3455 <option value="AK">Alaska</option>
       
  3456 <option value="AS">American Samoa</option>
       
  3457 <option value="AZ">Arizona</option>
       
  3458 <option value="AR">Arkansas</option>
       
  3459 <option value="CA">California</option>
       
  3460 <option value="CO">Colorado</option>
       
  3461 <option value="CT">Connecticut</option>
       
  3462 <option value="DE">Deleware</option>
       
  3463 <option value="DC">District of Columbia</option>
       
  3464 <option value="FM">Federated States of Micronesia</option>
       
  3465 <option value="FL">Florida</option>
       
  3466 <option value="GA">Georgia</option>
       
  3467 <option value="GU">Guam</option>
       
  3468 <option value="HI">Hawaii</option>
       
  3469 <option value="ID">Idaho</option>
       
  3470 <option value="IL" selected="selected">Illinois</option>
       
  3471 <option value="IN">Indiana</option>
       
  3472 <option value="IA">Iowa</option>
       
  3473 <option value="KS">Kansas</option>
       
  3474 <option value="KY">Kentucky</option>
       
  3475 <option value="LA">Louisiana</option>
       
  3476 <option value="ME">Maine</option>
       
  3477 <option value="MH">Marshall Islands</option>
       
  3478 <option value="MD">Maryland</option>
       
  3479 <option value="MA">Massachusetts</option>
       
  3480 <option value="MI">Michigan</option>
       
  3481 <option value="MN">Minnesota</option>
       
  3482 <option value="MS">Mississippi</option>
       
  3483 <option value="MO">Missouri</option>
       
  3484 <option value="MT">Montana</option>
       
  3485 <option value="NE">Nebraska</option>
       
  3486 <option value="NV">Nevada</option>
       
  3487 <option value="NH">New Hampshire</option>
       
  3488 <option value="NJ">New Jersey</option>
       
  3489 <option value="NM">New Mexico</option>
       
  3490 <option value="NY">New York</option>
       
  3491 <option value="NC">North Carolina</option>
       
  3492 <option value="ND">North Dakota</option>
       
  3493 <option value="MP">Northern Mariana Islands</option>
       
  3494 <option value="OH">Ohio</option>
       
  3495 <option value="OK">Oklahoma</option>
       
  3496 <option value="OR">Oregon</option>
       
  3497 <option value="PW">Palau</option>
       
  3498 <option value="PA">Pennsylvania</option>
       
  3499 <option value="PR">Puerto Rico</option>
       
  3500 <option value="RI">Rhode Island</option>
       
  3501 <option value="SC">South Carolina</option>
       
  3502 <option value="SD">South Dakota</option>
       
  3503 <option value="TN">Tennessee</option>
       
  3504 <option value="TX">Texas</option>
       
  3505 <option value="UT">Utah</option>
       
  3506 <option value="VT">Vermont</option>
       
  3507 <option value="VI">Virgin Islands</option>
       
  3508 <option value="VA">Virginia</option>
       
  3509 <option value="WA">Washington</option>
       
  3510 <option value="WV">West Virginia</option>
       
  3511 <option value="WI">Wisconsin</option>
       
  3512 <option value="WY">Wyoming</option>
       
  3513 </select>
       
  3514 
       
  3515 # UKPostcodeField #############################################################
       
  3516 
       
  3517 UKPostcodeField validates that the data is a valid UK postcode.
       
  3518 >>> from django.contrib.localflavor.uk.forms import UKPostcodeField
       
  3519 >>> f = UKPostcodeField()
       
  3520 >>> f.clean('BT32 4PX')
       
  3521 u'BT32 4PX'
       
  3522 >>> f.clean('GIR 0AA')
       
  3523 u'GIR 0AA'
       
  3524 >>> f.clean('BT324PX')
       
  3525 Traceback (most recent call last):
       
  3526 ...
       
  3527 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.']
       
  3528 >>> f.clean('1NV 4L1D')
       
  3529 Traceback (most recent call last):
       
  3530 ...
       
  3531 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.']
       
  3532 >>> f.clean(None)
       
  3533 Traceback (most recent call last):
       
  3534 ...
       
  3535 ValidationError: [u'This field is required.']
       
  3536 >>> f.clean('')
       
  3537 Traceback (most recent call last):
       
  3538 ...
       
  3539 ValidationError: [u'This field is required.']
       
  3540 
       
  3541 >>> f = UKPostcodeField(required=False)
       
  3542 >>> f.clean('BT32 4PX')
       
  3543 u'BT32 4PX'
       
  3544 >>> f.clean('GIR 0AA')
       
  3545 u'GIR 0AA'
       
  3546 >>> f.clean('1NV 4L1D')
       
  3547 Traceback (most recent call last):
       
  3548 ...
       
  3549 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.']
       
  3550 >>> f.clean('BT324PX')
       
  3551 Traceback (most recent call last):
       
  3552 ...
       
  3553 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.']
       
  3554 >>> f.clean(None)
       
  3555 u''
       
  3556 >>> f.clean('')
       
  3557 u''
       
  3558 
       
  3559 #################################
       
  3560 # Tests of underlying functions #
       
  3561 #################################
       
  3562 
       
  3563 # smart_unicode tests
       
  3564 >>> from django.newforms.util import smart_unicode
       
  3565 >>> class Test:
       
  3566 ...     def __str__(self):
       
  3567 ...        return 'ŠĐĆŽćžšđ'
       
  3568 >>> class TestU:
       
  3569 ...     def __str__(self):
       
  3570 ...        return 'Foo'
       
  3571 ...     def __unicode__(self):
       
  3572 ...        return u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
       
  3573 >>> smart_unicode(Test())
       
  3574 u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
       
  3575 >>> smart_unicode(TestU())
       
  3576 u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
       
  3577 >>> smart_unicode(1)
       
  3578 u'1'
       
  3579 >>> smart_unicode('foo')
       
  3580 u'foo'
       
  3581 """
       
  3582 
       
  3583 if __name__ == "__main__":
       
  3584     import doctest
       
  3585     doctest.testmod()