extra.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, unicode_literals
  3. import datetime
  4. from django.forms import *
  5. from django.forms.extras import SelectDateWidget
  6. from django.forms.util import ErrorList
  7. from django.test import TestCase
  8. from django.test.utils import override_settings
  9. from django.utils import six
  10. from django.utils import translation
  11. from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
  12. from .error_messages import AssertFormErrorsMixin
  13. class GetDate(Form):
  14. mydate = DateField(widget=SelectDateWidget)
  15. class GetNotRequiredDate(Form):
  16. mydate = DateField(widget=SelectDateWidget, required=False)
  17. class GetDateShowHiddenInitial(Form):
  18. mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
  19. class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
  20. ###############
  21. # Extra stuff #
  22. ###############
  23. # The forms library comes with some extra, higher-level Field and Widget
  24. def test_selectdate(self):
  25. w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
  26. self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
  27. <option value="0">---</option>
  28. <option value="1">January</option>
  29. <option value="2">February</option>
  30. <option value="3">March</option>
  31. <option value="4">April</option>
  32. <option value="5">May</option>
  33. <option value="6">June</option>
  34. <option value="7">July</option>
  35. <option value="8">August</option>
  36. <option value="9">September</option>
  37. <option value="10">October</option>
  38. <option value="11">November</option>
  39. <option value="12">December</option>
  40. </select>
  41. <select name="mydate_day" id="id_mydate_day">
  42. <option value="0">---</option>
  43. <option value="1">1</option>
  44. <option value="2">2</option>
  45. <option value="3">3</option>
  46. <option value="4">4</option>
  47. <option value="5">5</option>
  48. <option value="6">6</option>
  49. <option value="7">7</option>
  50. <option value="8">8</option>
  51. <option value="9">9</option>
  52. <option value="10">10</option>
  53. <option value="11">11</option>
  54. <option value="12">12</option>
  55. <option value="13">13</option>
  56. <option value="14">14</option>
  57. <option value="15">15</option>
  58. <option value="16">16</option>
  59. <option value="17">17</option>
  60. <option value="18">18</option>
  61. <option value="19">19</option>
  62. <option value="20">20</option>
  63. <option value="21">21</option>
  64. <option value="22">22</option>
  65. <option value="23">23</option>
  66. <option value="24">24</option>
  67. <option value="25">25</option>
  68. <option value="26">26</option>
  69. <option value="27">27</option>
  70. <option value="28">28</option>
  71. <option value="29">29</option>
  72. <option value="30">30</option>
  73. <option value="31">31</option>
  74. </select>
  75. <select name="mydate_year" id="id_mydate_year">
  76. <option value="0">---</option>
  77. <option value="2007">2007</option>
  78. <option value="2008">2008</option>
  79. <option value="2009">2009</option>
  80. <option value="2010">2010</option>
  81. <option value="2011">2011</option>
  82. <option value="2012">2012</option>
  83. <option value="2013">2013</option>
  84. <option value="2014">2014</option>
  85. <option value="2015">2015</option>
  86. <option value="2016">2016</option>
  87. </select>""")
  88. self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
  89. self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
  90. <option value="1">January</option>
  91. <option value="2">February</option>
  92. <option value="3">March</option>
  93. <option value="4" selected="selected">April</option>
  94. <option value="5">May</option>
  95. <option value="6">June</option>
  96. <option value="7">July</option>
  97. <option value="8">August</option>
  98. <option value="9">September</option>
  99. <option value="10">October</option>
  100. <option value="11">November</option>
  101. <option value="12">December</option>
  102. </select>
  103. <select name="mydate_day" id="id_mydate_day">
  104. <option value="1">1</option>
  105. <option value="2">2</option>
  106. <option value="3">3</option>
  107. <option value="4">4</option>
  108. <option value="5">5</option>
  109. <option value="6">6</option>
  110. <option value="7">7</option>
  111. <option value="8">8</option>
  112. <option value="9">9</option>
  113. <option value="10">10</option>
  114. <option value="11">11</option>
  115. <option value="12">12</option>
  116. <option value="13">13</option>
  117. <option value="14">14</option>
  118. <option value="15" selected="selected">15</option>
  119. <option value="16">16</option>
  120. <option value="17">17</option>
  121. <option value="18">18</option>
  122. <option value="19">19</option>
  123. <option value="20">20</option>
  124. <option value="21">21</option>
  125. <option value="22">22</option>
  126. <option value="23">23</option>
  127. <option value="24">24</option>
  128. <option value="25">25</option>
  129. <option value="26">26</option>
  130. <option value="27">27</option>
  131. <option value="28">28</option>
  132. <option value="29">29</option>
  133. <option value="30">30</option>
  134. <option value="31">31</option>
  135. </select>
  136. <select name="mydate_year" id="id_mydate_year">
  137. <option value="2007">2007</option>
  138. <option value="2008">2008</option>
  139. <option value="2009">2009</option>
  140. <option value="2010" selected="selected">2010</option>
  141. <option value="2011">2011</option>
  142. <option value="2012">2012</option>
  143. <option value="2013">2013</option>
  144. <option value="2014">2014</option>
  145. <option value="2015">2015</option>
  146. <option value="2016">2016</option>
  147. </select>""")
  148. # Accepts a datetime or a string:
  149. self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
  150. # Invalid dates still render the failed date:
  151. self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
  152. <option value="1">January</option>
  153. <option value="2" selected="selected">February</option>
  154. <option value="3">March</option>
  155. <option value="4">April</option>
  156. <option value="5">May</option>
  157. <option value="6">June</option>
  158. <option value="7">July</option>
  159. <option value="8">August</option>
  160. <option value="9">September</option>
  161. <option value="10">October</option>
  162. <option value="11">November</option>
  163. <option value="12">December</option>
  164. </select>
  165. <select name="mydate_day" id="id_mydate_day">
  166. <option value="1">1</option>
  167. <option value="2">2</option>
  168. <option value="3">3</option>
  169. <option value="4">4</option>
  170. <option value="5">5</option>
  171. <option value="6">6</option>
  172. <option value="7">7</option>
  173. <option value="8">8</option>
  174. <option value="9">9</option>
  175. <option value="10">10</option>
  176. <option value="11">11</option>
  177. <option value="12">12</option>
  178. <option value="13">13</option>
  179. <option value="14">14</option>
  180. <option value="15">15</option>
  181. <option value="16">16</option>
  182. <option value="17">17</option>
  183. <option value="18">18</option>
  184. <option value="19">19</option>
  185. <option value="20">20</option>
  186. <option value="21">21</option>
  187. <option value="22">22</option>
  188. <option value="23">23</option>
  189. <option value="24">24</option>
  190. <option value="25">25</option>
  191. <option value="26">26</option>
  192. <option value="27">27</option>
  193. <option value="28">28</option>
  194. <option value="29">29</option>
  195. <option value="30">30</option>
  196. <option value="31" selected="selected">31</option>
  197. </select>
  198. <select name="mydate_year" id="id_mydate_year">
  199. <option value="2007">2007</option>
  200. <option value="2008">2008</option>
  201. <option value="2009">2009</option>
  202. <option value="2010" selected="selected">2010</option>
  203. <option value="2011">2011</option>
  204. <option value="2012">2012</option>
  205. <option value="2013">2013</option>
  206. <option value="2014">2014</option>
  207. <option value="2015">2015</option>
  208. <option value="2016">2016</option>
  209. </select>""")
  210. # Using a SelectDateWidget in a form:
  211. w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
  212. self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
  213. <option value="0">---</option>
  214. <option value="1">January</option>
  215. <option value="2">February</option>
  216. <option value="3">March</option>
  217. <option value="4">April</option>
  218. <option value="5">May</option>
  219. <option value="6">June</option>
  220. <option value="7">July</option>
  221. <option value="8">August</option>
  222. <option value="9">September</option>
  223. <option value="10">October</option>
  224. <option value="11">November</option>
  225. <option value="12">December</option>
  226. </select>
  227. <select name="mydate_day" id="id_mydate_day">
  228. <option value="0">---</option>
  229. <option value="1">1</option>
  230. <option value="2">2</option>
  231. <option value="3">3</option>
  232. <option value="4">4</option>
  233. <option value="5">5</option>
  234. <option value="6">6</option>
  235. <option value="7">7</option>
  236. <option value="8">8</option>
  237. <option value="9">9</option>
  238. <option value="10">10</option>
  239. <option value="11">11</option>
  240. <option value="12">12</option>
  241. <option value="13">13</option>
  242. <option value="14">14</option>
  243. <option value="15">15</option>
  244. <option value="16">16</option>
  245. <option value="17">17</option>
  246. <option value="18">18</option>
  247. <option value="19">19</option>
  248. <option value="20">20</option>
  249. <option value="21">21</option>
  250. <option value="22">22</option>
  251. <option value="23">23</option>
  252. <option value="24">24</option>
  253. <option value="25">25</option>
  254. <option value="26">26</option>
  255. <option value="27">27</option>
  256. <option value="28">28</option>
  257. <option value="29">29</option>
  258. <option value="30">30</option>
  259. <option value="31">31</option>
  260. </select>
  261. <select name="mydate_year" id="id_mydate_year">
  262. <option value="0">---</option>
  263. <option value="2007">2007</option>
  264. <option value="2008">2008</option>
  265. <option value="2009">2009</option>
  266. <option value="2010">2010</option>
  267. <option value="2011">2011</option>
  268. <option value="2012">2012</option>
  269. <option value="2013">2013</option>
  270. <option value="2014">2014</option>
  271. <option value="2015">2015</option>
  272. <option value="2016">2016</option>
  273. </select>""")
  274. self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
  275. <option value="0">---</option>
  276. <option value="1">January</option>
  277. <option value="2">February</option>
  278. <option value="3">March</option>
  279. <option value="4" selected="selected">April</option>
  280. <option value="5">May</option>
  281. <option value="6">June</option>
  282. <option value="7">July</option>
  283. <option value="8">August</option>
  284. <option value="9">September</option>
  285. <option value="10">October</option>
  286. <option value="11">November</option>
  287. <option value="12">December</option>
  288. </select>
  289. <select name="mydate_day" id="id_mydate_day">
  290. <option value="0">---</option>
  291. <option value="1">1</option>
  292. <option value="2">2</option>
  293. <option value="3">3</option>
  294. <option value="4">4</option>
  295. <option value="5">5</option>
  296. <option value="6">6</option>
  297. <option value="7">7</option>
  298. <option value="8">8</option>
  299. <option value="9">9</option>
  300. <option value="10">10</option>
  301. <option value="11">11</option>
  302. <option value="12">12</option>
  303. <option value="13">13</option>
  304. <option value="14">14</option>
  305. <option value="15" selected="selected">15</option>
  306. <option value="16">16</option>
  307. <option value="17">17</option>
  308. <option value="18">18</option>
  309. <option value="19">19</option>
  310. <option value="20">20</option>
  311. <option value="21">21</option>
  312. <option value="22">22</option>
  313. <option value="23">23</option>
  314. <option value="24">24</option>
  315. <option value="25">25</option>
  316. <option value="26">26</option>
  317. <option value="27">27</option>
  318. <option value="28">28</option>
  319. <option value="29">29</option>
  320. <option value="30">30</option>
  321. <option value="31">31</option>
  322. </select>
  323. <select name="mydate_year" id="id_mydate_year">
  324. <option value="0">---</option>
  325. <option value="2007">2007</option>
  326. <option value="2008">2008</option>
  327. <option value="2009">2009</option>
  328. <option value="2010" selected="selected">2010</option>
  329. <option value="2011">2011</option>
  330. <option value="2012">2012</option>
  331. <option value="2013">2013</option>
  332. <option value="2014">2014</option>
  333. <option value="2015">2015</option>
  334. <option value="2016">2016</option>
  335. </select>""")
  336. a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'})
  337. self.assertTrue(a.is_valid())
  338. self.assertEqual(a.cleaned_data['mydate'], datetime.date(2008, 4, 1))
  339. # As with any widget that implements get_value_from_datadict,
  340. # we must be prepared to accept the input from the "as_hidden"
  341. # rendering as well.
  342. self.assertHTMLEqual(a['mydate'].as_hidden(), '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />')
  343. b = GetDate({'mydate':'2008-4-1'})
  344. self.assertTrue(b.is_valid())
  345. self.assertEqual(b.cleaned_data['mydate'], datetime.date(2008, 4, 1))
  346. # Invalid dates shouldn't be allowed
  347. c = GetDate({'mydate_month':'2', 'mydate_day':'31', 'mydate_year':'2010'})
  348. self.assertFalse(c.is_valid())
  349. self.assertEqual(c.errors, {'mydate': ['Enter a valid date.']})
  350. # label tag is correctly associated with month dropdown
  351. d = GetDate({'mydate_month':'1', 'mydate_day':'1', 'mydate_year':'2010'})
  352. self.assertTrue('<label for="id_mydate_month">' in d.as_p())
  353. def test_multiwidget(self):
  354. # MultiWidget and MultiValueField #############################################
  355. # MultiWidgets are widgets composed of other widgets. They are usually
  356. # combined with MultiValueFields - a field that is composed of other fields.
  357. # MulitWidgets can themselved be composed of other MultiWidgets.
  358. # SplitDateTimeWidget is one example of a MultiWidget.
  359. class ComplexMultiWidget(MultiWidget):
  360. def __init__(self, attrs=None):
  361. widgets = (
  362. TextInput(),
  363. SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
  364. SplitDateTimeWidget(),
  365. )
  366. super(ComplexMultiWidget, self).__init__(widgets, attrs)
  367. def decompress(self, value):
  368. if value:
  369. data = value.split(',')
  370. return [data[0], data[1], datetime.datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S")]
  371. return [None, None, None]
  372. def format_output(self, rendered_widgets):
  373. return '\n'.join(rendered_widgets)
  374. w = ComplexMultiWidget()
  375. self.assertHTMLEqual(w.render('name', 'some text,JP,2007-04-25 06:24:00'), """<input type="text" name="name_0" value="some text" />
  376. <select multiple="multiple" name="name_1">
  377. <option value="J" selected="selected">John</option>
  378. <option value="P" selected="selected">Paul</option>
  379. <option value="G">George</option>
  380. <option value="R">Ringo</option>
  381. </select>
  382. <input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />""")
  383. class ComplexField(MultiValueField):
  384. def __init__(self, required=True, widget=None, label=None, initial=None):
  385. fields = (
  386. CharField(),
  387. MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
  388. SplitDateTimeField()
  389. )
  390. super(ComplexField, self).__init__(fields, required, widget, label, initial)
  391. def compress(self, data_list):
  392. if data_list:
  393. return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
  394. return None
  395. f = ComplexField(widget=w)
  396. self.assertEqual(f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']]), 'some text,JP,2007-04-25 06:24:00')
  397. self.assertFormErrors(['Select a valid choice. X is not one of the available choices.'], f.clean, ['some text',['X'], ['2007-04-25','6:24:00']])
  398. # If insufficient data is provided, None is substituted
  399. self.assertFormErrors(['This field is required.'], f.clean, ['some text',['JP']])
  400. # test with no initial data
  401. self.assertTrue(f._has_changed(None, ['some text', ['J','P'], ['2007-04-25','6:24:00']]))
  402. # test when the data is the same as initial
  403. self.assertFalse(f._has_changed('some text,JP,2007-04-25 06:24:00',
  404. ['some text', ['J','P'], ['2007-04-25','6:24:00']]))
  405. # test when the first widget's data has changed
  406. self.assertTrue(f._has_changed('some text,JP,2007-04-25 06:24:00',
  407. ['other text', ['J','P'], ['2007-04-25','6:24:00']]))
  408. # test when the last widget's data has changed. this ensures that it is not
  409. # short circuiting while testing the widgets.
  410. self.assertTrue(f._has_changed('some text,JP,2007-04-25 06:24:00',
  411. ['some text', ['J','P'], ['2009-04-25','11:44:00']]))
  412. class ComplexFieldForm(Form):
  413. field1 = ComplexField(widget=w)
  414. f = ComplexFieldForm()
  415. self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
  416. <select multiple="multiple" name="field1_1" id="id_field1_1">
  417. <option value="J">John</option>
  418. <option value="P">Paul</option>
  419. <option value="G">George</option>
  420. <option value="R">Ringo</option>
  421. </select>
  422. <input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>""")
  423. f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
  424. self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
  425. <select multiple="multiple" name="field1_1" id="id_field1_1">
  426. <option value="J" selected="selected">John</option>
  427. <option value="P" selected="selected">Paul</option>
  428. <option value="G">George</option>
  429. <option value="R">Ringo</option>
  430. </select>
  431. <input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>""")
  432. self.assertEqual(f.cleaned_data['field1'], 'some text,JP,2007-04-25 06:24:00')
  433. def test_ipaddress(self):
  434. f = IPAddressField()
  435. self.assertFormErrors(['This field is required.'], f.clean, '')
  436. self.assertFormErrors(['This field is required.'], f.clean, None)
  437. self.assertEqual(f.clean(' 127.0.0.1'), '127.0.0.1')
  438. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
  439. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
  440. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
  441. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
  442. f = IPAddressField(required=False)
  443. self.assertEqual(f.clean(''), '')
  444. self.assertEqual(f.clean(None), '')
  445. self.assertEqual(f.clean(' 127.0.0.1'), '127.0.0.1')
  446. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
  447. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
  448. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
  449. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
  450. def test_generic_ipaddress_invalid_arguments(self):
  451. self.assertRaises(ValueError, GenericIPAddressField, protocol="hamster")
  452. self.assertRaises(ValueError, GenericIPAddressField, protocol="ipv4", unpack_ipv4=True)
  453. def test_generic_ipaddress_as_generic(self):
  454. # The edge cases of the IPv6 validation code are not deeply tested
  455. # here, they are covered in the tests for django.utils.ipv6
  456. f = GenericIPAddressField()
  457. self.assertFormErrors(['This field is required.'], f.clean, '')
  458. self.assertFormErrors(['This field is required.'], f.clean, None)
  459. self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
  460. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo')
  461. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.')
  462. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5')
  463. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
  464. self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
  465. self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
  466. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4')
  467. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4')
  468. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
  469. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
  470. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2')
  471. def test_generic_ipaddress_as_ipv4_only(self):
  472. f = GenericIPAddressField(protocol="IPv4")
  473. self.assertFormErrors(['This field is required.'], f.clean, '')
  474. self.assertFormErrors(['This field is required.'], f.clean, None)
  475. self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
  476. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
  477. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
  478. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
  479. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
  480. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'fe80::223:6cff:fe8a:2e8a')
  481. self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '2a02::223:6cff:fe8a:2e8a')
  482. def test_generic_ipaddress_as_ipv6_only(self):
  483. f = GenericIPAddressField(protocol="IPv6")
  484. self.assertFormErrors(['This field is required.'], f.clean, '')
  485. self.assertFormErrors(['This field is required.'], f.clean, None)
  486. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '127.0.0.1')
  487. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, 'foo')
  488. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '127.0.0.')
  489. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1.2.3.4.5')
  490. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '256.125.1.5')
  491. self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
  492. self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
  493. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '12345:2:3:4')
  494. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1::2:3::4')
  495. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
  496. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
  497. self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1:2')
  498. def test_generic_ipaddress_as_generic_not_required(self):
  499. f = GenericIPAddressField(required=False)
  500. self.assertEqual(f.clean(''), '')
  501. self.assertEqual(f.clean(None), '')
  502. self.assertEqual(f.clean('127.0.0.1'), '127.0.0.1')
  503. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo')
  504. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.')
  505. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5')
  506. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
  507. self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
  508. self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
  509. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4')
  510. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4')
  511. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
  512. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
  513. self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2')
  514. def test_generic_ipaddress_normalization(self):
  515. # Test the normalising code
  516. f = GenericIPAddressField()
  517. self.assertEqual(f.clean(' ::ffff:0a0a:0a0a '), '::ffff:10.10.10.10')
  518. self.assertEqual(f.clean(' ::ffff:10.10.10.10 '), '::ffff:10.10.10.10')
  519. self.assertEqual(f.clean(' 2001:000:a:0000:0:fe:fe:beef '), '2001:0:a::fe:fe:beef')
  520. self.assertEqual(f.clean(' 2001::a:0000:0:fe:fe:beef '), '2001:0:a::fe:fe:beef')
  521. f = GenericIPAddressField(unpack_ipv4=True)
  522. self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10')
  523. def test_smart_text(self):
  524. class Test:
  525. if six.PY3:
  526. def __str__(self):
  527. return 'ŠĐĆŽćžšđ'
  528. else:
  529. def __str__(self):
  530. return 'ŠĐĆŽćžšđ'.encode('utf-8')
  531. class TestU:
  532. if six.PY3:
  533. def __str__(self):
  534. return 'ŠĐĆŽćžšđ'
  535. def __bytes__(self):
  536. return b'Foo'
  537. else:
  538. def __str__(self):
  539. return b'Foo'
  540. def __unicode__(self):
  541. return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
  542. self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
  543. self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
  544. self.assertEqual(smart_text(1), '1')
  545. self.assertEqual(smart_text('foo'), 'foo')
  546. def test_accessing_clean(self):
  547. class UserForm(Form):
  548. username = CharField(max_length=10)
  549. password = CharField(widget=PasswordInput)
  550. def clean(self):
  551. data = self.cleaned_data
  552. if not self.errors:
  553. data['username'] = data['username'].lower()
  554. return data
  555. f = UserForm({'username': 'SirRobin', 'password': 'blue'})
  556. self.assertTrue(f.is_valid())
  557. self.assertEqual(f.cleaned_data['username'], 'sirrobin')
  558. def test_overriding_errorlist(self):
  559. @python_2_unicode_compatible
  560. class DivErrorList(ErrorList):
  561. def __str__(self):
  562. return self.as_divs()
  563. def as_divs(self):
  564. if not self: return ''
  565. return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % force_text(e) for e in self])
  566. class CommentForm(Form):
  567. name = CharField(max_length=50, required=False)
  568. email = EmailField()
  569. comment = CharField()
  570. data = dict(email='invalid')
  571. f = CommentForm(data, auto_id=False, error_class=DivErrorList)
  572. self.assertHTMLEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
  573. <div class="errorlist"><div class="error">Enter a valid email address.</div></div>
  574. <p>Email: <input type="email" name="email" value="invalid" /></p>
  575. <div class="errorlist"><div class="error">This field is required.</div></div>
  576. <p>Comment: <input type="text" name="comment" /></p>""")
  577. def test_multipart_encoded_form(self):
  578. class FormWithoutFile(Form):
  579. username = CharField()
  580. class FormWithFile(Form):
  581. username = CharField()
  582. file = FileField()
  583. class FormWithImage(Form):
  584. image = ImageField()
  585. self.assertFalse(FormWithoutFile().is_multipart())
  586. self.assertTrue(FormWithFile().is_multipart())
  587. self.assertTrue(FormWithImage().is_multipart())
  588. def test_field_not_required(self):
  589. b = GetNotRequiredDate({
  590. 'mydate_year': '',
  591. 'mydate_month': '',
  592. 'mydate_day': ''
  593. })
  594. self.assertFalse(b.has_changed())
  595. @override_settings(USE_L10N=True)
  596. class FormsExtraL10NTestCase(TestCase):
  597. def setUp(self):
  598. super(FormsExtraL10NTestCase, self).setUp()
  599. translation.activate('nl')
  600. def tearDown(self):
  601. translation.deactivate()
  602. super(FormsExtraL10NTestCase, self).tearDown()
  603. def test_l10n(self):
  604. w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
  605. self.assertEqual(w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-2010')
  606. self.assertHTMLEqual(w.render('date', '13-08-2010'), """<select name="date_day" id="id_date_day">
  607. <option value="0">---</option>
  608. <option value="1">1</option>
  609. <option value="2">2</option>
  610. <option value="3">3</option>
  611. <option value="4">4</option>
  612. <option value="5">5</option>
  613. <option value="6">6</option>
  614. <option value="7">7</option>
  615. <option value="8">8</option>
  616. <option value="9">9</option>
  617. <option value="10">10</option>
  618. <option value="11">11</option>
  619. <option value="12">12</option>
  620. <option value="13" selected="selected">13</option>
  621. <option value="14">14</option>
  622. <option value="15">15</option>
  623. <option value="16">16</option>
  624. <option value="17">17</option>
  625. <option value="18">18</option>
  626. <option value="19">19</option>
  627. <option value="20">20</option>
  628. <option value="21">21</option>
  629. <option value="22">22</option>
  630. <option value="23">23</option>
  631. <option value="24">24</option>
  632. <option value="25">25</option>
  633. <option value="26">26</option>
  634. <option value="27">27</option>
  635. <option value="28">28</option>
  636. <option value="29">29</option>
  637. <option value="30">30</option>
  638. <option value="31">31</option>
  639. </select>
  640. <select name="date_month" id="id_date_month">
  641. <option value="0">---</option>
  642. <option value="1">januari</option>
  643. <option value="2">februari</option>
  644. <option value="3">maart</option>
  645. <option value="4">april</option>
  646. <option value="5">mei</option>
  647. <option value="6">juni</option>
  648. <option value="7">juli</option>
  649. <option value="8" selected="selected">augustus</option>
  650. <option value="9">september</option>
  651. <option value="10">oktober</option>
  652. <option value="11">november</option>
  653. <option value="12">december</option>
  654. </select>
  655. <select name="date_year" id="id_date_year">
  656. <option value="0">---</option>
  657. <option value="2007">2007</option>
  658. <option value="2008">2008</option>
  659. <option value="2009">2009</option>
  660. <option value="2010" selected="selected">2010</option>
  661. <option value="2011">2011</option>
  662. <option value="2012">2012</option>
  663. <option value="2013">2013</option>
  664. <option value="2014">2014</option>
  665. <option value="2015">2015</option>
  666. <option value="2016">2016</option>
  667. </select>""")
  668. # Years before 1900 work
  669. w = SelectDateWidget(years=('1899',))
  670. self.assertEqual(w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-1899')
  671. def test_l10n_date_changed(self):
  672. """
  673. Ensure that DateField._has_changed() with SelectDateWidget works
  674. correctly with a localized date format.
  675. Refs #17165.
  676. """
  677. # With Field.show_hidden_initial=False -----------------------
  678. b = GetDate({
  679. 'mydate_year': '2008',
  680. 'mydate_month': '4',
  681. 'mydate_day': '1',
  682. }, initial={'mydate': datetime.date(2008, 4, 1)})
  683. self.assertFalse(b.has_changed())
  684. b = GetDate({
  685. 'mydate_year': '2008',
  686. 'mydate_month': '4',
  687. 'mydate_day': '2',
  688. }, initial={'mydate': datetime.date(2008, 4, 1)})
  689. self.assertTrue(b.has_changed())
  690. # With Field.show_hidden_initial=True ------------------------
  691. b = GetDateShowHiddenInitial({
  692. 'mydate_year': '2008',
  693. 'mydate_month': '4',
  694. 'mydate_day': '1',
  695. 'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
  696. }, initial={'mydate': datetime.date(2008, 4, 1)})
  697. self.assertFalse(b.has_changed())
  698. b = GetDateShowHiddenInitial({
  699. 'mydate_year': '2008',
  700. 'mydate_month': '4',
  701. 'mydate_day': '22',
  702. 'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
  703. }, initial={'mydate': datetime.date(2008, 4, 1)})
  704. self.assertTrue(b.has_changed())
  705. b = GetDateShowHiddenInitial({
  706. 'mydate_year': '2008',
  707. 'mydate_month': '4',
  708. 'mydate_day': '22',
  709. 'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
  710. }, initial={'mydate': datetime.date(2008, 4, 22)})
  711. self.assertTrue(b.has_changed())
  712. b = GetDateShowHiddenInitial({
  713. 'mydate_year': '2008',
  714. 'mydate_month': '4',
  715. 'mydate_day': '22',
  716. 'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 22))
  717. }, initial={'mydate': datetime.date(2008, 4, 1)})
  718. self.assertFalse(b.has_changed())
  719. def test_l10n_invalid_date_in(self):
  720. # Invalid dates shouldn't be allowed
  721. a = GetDate({'mydate_month':'2', 'mydate_day':'31', 'mydate_year':'2010'})
  722. self.assertFalse(a.is_valid())
  723. # 'Geef een geldige datum op.' = 'Enter a valid date.'
  724. self.assertEqual(a.errors, {'mydate': ['Geef een geldige datum op.']})
  725. def test_form_label_association(self):
  726. # label tag is correctly associated with first rendered dropdown
  727. a = GetDate({'mydate_month':'1', 'mydate_day':'1', 'mydate_year':'2010'})
  728. self.assertTrue('<label for="id_mydate_day">' in a.as_p())