fields.py 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. # -*- coding: utf-8 -*-
  2. """
  3. ##########
  4. # Fields #
  5. ##########
  6. Each Field class does some sort of validation. Each Field has a clean() method,
  7. which either raises django.forms.ValidationError or returns the "clean"
  8. data -- usually a Unicode object, but, in some rare cases, a list.
  9. Each Field's __init__() takes at least these parameters:
  10. required -- Boolean that specifies whether the field is required.
  11. True by default.
  12. widget -- A Widget class, or instance of a Widget class, that should be
  13. used for this Field when displaying it. Each Field has a default
  14. Widget that it'll use if you don't specify this. In most cases,
  15. the default widget is TextInput.
  16. label -- A verbose name for this field, for use in displaying this field in
  17. a form. By default, Django will use a "pretty" version of the form
  18. field name, if the Field is part of a Form.
  19. initial -- A value to use in this Field's initial display. This value is
  20. *not* used as a fallback if data isn't given.
  21. Other than that, the Field subclasses have class-specific options for
  22. __init__(). For example, CharField has a max_length option.
  23. """
  24. import datetime
  25. import time
  26. import re
  27. import os
  28. from unittest import TestCase
  29. from django.core.files.uploadedfile import SimpleUploadedFile
  30. from django.forms import *
  31. from django.forms.widgets import RadioFieldRenderer
  32. try:
  33. from decimal import Decimal
  34. except ImportError:
  35. from django.utils._decimal import Decimal
  36. def fix_os_paths(x):
  37. if isinstance(x, basestring):
  38. return x.replace('\\', '/')
  39. elif isinstance(x, tuple):
  40. return tuple(fix_os_paths(list(x)))
  41. elif isinstance(x, list):
  42. return [fix_os_paths(y) for y in x]
  43. else:
  44. return x
  45. class FieldsTests(TestCase):
  46. def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
  47. self.assertRaises(error, callable, *args, **kwargs)
  48. try:
  49. callable(*args, **kwargs)
  50. except error, e:
  51. self.assertEqual(message, str(e))
  52. # CharField ###################################################################
  53. def test_charfield_0(self):
  54. f = CharField()
  55. self.assertEqual(u'1', f.clean(1))
  56. self.assertEqual(u'hello', f.clean('hello'))
  57. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  58. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  59. self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3]))
  60. def test_charfield_1(self):
  61. f = CharField(required=False)
  62. self.assertEqual(u'1', f.clean(1))
  63. self.assertEqual(u'hello', f.clean('hello'))
  64. self.assertEqual(u'', f.clean(None))
  65. self.assertEqual(u'', f.clean(''))
  66. self.assertEqual(u'[1, 2, 3]', f.clean([1, 2, 3]))
  67. def test_charfield_2(self):
  68. f = CharField(max_length=10, required=False)
  69. self.assertEqual(u'12345', f.clean('12345'))
  70. self.assertEqual(u'1234567890', f.clean('1234567890'))
  71. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '1234567890a')
  72. def test_charfield_3(self):
  73. f = CharField(min_length=10, required=False)
  74. self.assertEqual(u'', f.clean(''))
  75. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345')
  76. self.assertEqual(u'1234567890', f.clean('1234567890'))
  77. self.assertEqual(u'1234567890a', f.clean('1234567890a'))
  78. def test_charfield_4(self):
  79. f = CharField(min_length=10, required=True)
  80. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  81. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 5).']", f.clean, '12345')
  82. self.assertEqual(u'1234567890', f.clean('1234567890'))
  83. self.assertEqual(u'1234567890a', f.clean('1234567890a'))
  84. # IntegerField ################################################################
  85. def test_integerfield_5(self):
  86. f = IntegerField()
  87. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  88. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  89. self.assertEqual(1, f.clean('1'))
  90. self.assertEqual(True, isinstance(f.clean('1'), int))
  91. self.assertEqual(23, f.clean('23'))
  92. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a')
  93. self.assertEqual(42, f.clean(42))
  94. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 3.14)
  95. self.assertEqual(1, f.clean('1 '))
  96. self.assertEqual(1, f.clean(' 1'))
  97. self.assertEqual(1, f.clean(' 1 '))
  98. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a')
  99. def test_integerfield_6(self):
  100. f = IntegerField(required=False)
  101. self.assertEqual(None, f.clean(''))
  102. self.assertEqual('None', repr(f.clean('')))
  103. self.assertEqual(None, f.clean(None))
  104. self.assertEqual('None', repr(f.clean(None)))
  105. self.assertEqual(1, f.clean('1'))
  106. self.assertEqual(True, isinstance(f.clean('1'), int))
  107. self.assertEqual(23, f.clean('23'))
  108. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, 'a')
  109. self.assertEqual(1, f.clean('1 '))
  110. self.assertEqual(1, f.clean(' 1'))
  111. self.assertEqual(1, f.clean(' 1 '))
  112. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a whole number.']", f.clean, '1a')
  113. def test_integerfield_7(self):
  114. f = IntegerField(max_value=10)
  115. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  116. self.assertEqual(1, f.clean(1))
  117. self.assertEqual(10, f.clean(10))
  118. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, 11)
  119. self.assertEqual(10, f.clean('10'))
  120. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 10.']", f.clean, '11')
  121. def test_integerfield_8(self):
  122. f = IntegerField(min_value=10)
  123. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  124. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1)
  125. self.assertEqual(10, f.clean(10))
  126. self.assertEqual(11, f.clean(11))
  127. self.assertEqual(10, f.clean('10'))
  128. self.assertEqual(11, f.clean('11'))
  129. def test_integerfield_9(self):
  130. f = IntegerField(min_value=10, max_value=20)
  131. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  132. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 10.']", f.clean, 1)
  133. self.assertEqual(10, f.clean(10))
  134. self.assertEqual(11, f.clean(11))
  135. self.assertEqual(10, f.clean('10'))
  136. self.assertEqual(11, f.clean('11'))
  137. self.assertEqual(20, f.clean(20))
  138. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 20.']", f.clean, 21)
  139. # FloatField ##################################################################
  140. def test_floatfield_10(self):
  141. f = FloatField()
  142. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  143. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  144. self.assertEqual(1.0, f.clean('1'))
  145. self.assertEqual(True, isinstance(f.clean('1'), float))
  146. self.assertEqual(23.0, f.clean('23'))
  147. self.assertEqual(3.1400000000000001, f.clean('3.14'))
  148. self.assertEqual(3.1400000000000001, f.clean(3.14))
  149. self.assertEqual(42.0, f.clean(42))
  150. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a')
  151. self.assertEqual(1.0, f.clean('1.0 '))
  152. self.assertEqual(1.0, f.clean(' 1.0'))
  153. self.assertEqual(1.0, f.clean(' 1.0 '))
  154. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a')
  155. def test_floatfield_11(self):
  156. f = FloatField(required=False)
  157. self.assertEqual(None, f.clean(''))
  158. self.assertEqual(None, f.clean(None))
  159. self.assertEqual(1.0, f.clean('1'))
  160. def test_floatfield_12(self):
  161. f = FloatField(max_value=1.5, min_value=0.5)
  162. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6')
  163. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4')
  164. self.assertEqual(1.5, f.clean('1.5'))
  165. self.assertEqual(0.5, f.clean('0.5'))
  166. # DecimalField ################################################################
  167. def test_decimalfield_13(self):
  168. f = DecimalField(max_digits=4, decimal_places=2)
  169. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  170. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  171. self.assertEqual(f.clean('1'), Decimal("1"))
  172. self.assertEqual(True, isinstance(f.clean('1'), Decimal))
  173. self.assertEqual(f.clean('23'), Decimal("23"))
  174. self.assertEqual(f.clean('3.14'), Decimal("3.14"))
  175. self.assertEqual(f.clean(3.14), Decimal("3.14"))
  176. self.assertEqual(f.clean(Decimal('3.14')), Decimal("3.14"))
  177. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a')
  178. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, u'łąść')
  179. self.assertEqual(f.clean('1.0 '), Decimal("1.0"))
  180. self.assertEqual(f.clean(' 1.0'), Decimal("1.0"))
  181. self.assertEqual(f.clean(' 1.0 '), Decimal("1.0"))
  182. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '1.0a')
  183. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '123.45')
  184. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '1.234')
  185. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 digits before the decimal point.']", f.clean, '123.4')
  186. self.assertEqual(f.clean('-12.34'), Decimal("-12.34"))
  187. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-123.45')
  188. self.assertEqual(f.clean('-.12'), Decimal("-0.12"))
  189. self.assertEqual(f.clean('-00.12'), Decimal("-0.12"))
  190. self.assertEqual(f.clean('-000.12'), Decimal("-0.12"))
  191. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '-000.123')
  192. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 4 digits in total.']", f.clean, '-000.12345')
  193. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '--0.12')
  194. def test_decimalfield_14(self):
  195. f = DecimalField(max_digits=4, decimal_places=2, required=False)
  196. self.assertEqual(None, f.clean(''))
  197. self.assertEqual(None, f.clean(None))
  198. self.assertEqual(f.clean('1'), Decimal("1"))
  199. def test_decimalfield_15(self):
  200. f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
  201. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is less than or equal to 1.5.']", f.clean, '1.6')
  202. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4')
  203. self.assertEqual(f.clean('1.5'), Decimal("1.5"))
  204. self.assertEqual(f.clean('0.5'), Decimal("0.5"))
  205. self.assertEqual(f.clean('.5'), Decimal("0.5"))
  206. self.assertEqual(f.clean('00.50'), Decimal("0.50"))
  207. def test_decimalfield_16(self):
  208. f = DecimalField(decimal_places=2)
  209. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 2 decimal places.']", f.clean, '0.00000001')
  210. def test_decimalfield_17(self):
  211. f = DecimalField(max_digits=3)
  212. # Leading whole zeros "collapse" to one digit.
  213. self.assertEqual(f.clean('0000000.10'), Decimal("0.1"))
  214. # But a leading 0 before the . doesn't count towards max_digits
  215. self.assertEqual(f.clean('0000000.100'), Decimal("0.100"))
  216. # Only leading whole zeros "collapse" to one digit.
  217. self.assertEqual(f.clean('000000.02'), Decimal('0.02'))
  218. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 3 digits in total.']", f.clean, '000000.0002')
  219. self.assertEqual(f.clean('.002'), Decimal("0.002"))
  220. def test_decimalfield_18(self):
  221. f = DecimalField(max_digits=2, decimal_places=2)
  222. self.assertEqual(f.clean('.01'), Decimal(".01"))
  223. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure that there are no more than 0 digits before the decimal point.']", f.clean, '1.1')
  224. # DateField ###################################################################
  225. def test_datefield_19(self):
  226. f = DateField()
  227. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25)))
  228. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
  229. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
  230. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
  231. self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006-10-25'))
  232. self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/2006'))
  233. self.assertEqual(datetime.date(2006, 10, 25), f.clean('10/25/06'))
  234. self.assertEqual(datetime.date(2006, 10, 25), f.clean('Oct 25 2006'))
  235. self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25 2006'))
  236. self.assertEqual(datetime.date(2006, 10, 25), f.clean('October 25, 2006'))
  237. self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October 2006'))
  238. self.assertEqual(datetime.date(2006, 10, 25), f.clean('25 October, 2006'))
  239. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-4-31')
  240. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '200a-10-25')
  241. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '25/10/06')
  242. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  243. def test_datefield_20(self):
  244. f = DateField(required=False)
  245. self.assertEqual(None, f.clean(None))
  246. self.assertEqual('None', repr(f.clean(None)))
  247. self.assertEqual(None, f.clean(''))
  248. self.assertEqual('None', repr(f.clean('')))
  249. def test_datefield_21(self):
  250. f = DateField(input_formats=['%Y %m %d'])
  251. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.date(2006, 10, 25)))
  252. self.assertEqual(datetime.date(2006, 10, 25), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
  253. self.assertEqual(datetime.date(2006, 10, 25), f.clean('2006 10 25'))
  254. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '2006-10-25')
  255. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/2006')
  256. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/06')
  257. # TimeField ###################################################################
  258. def test_timefield_22(self):
  259. f = TimeField()
  260. self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
  261. self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
  262. self.assertEqual(datetime.time(14, 25), f.clean('14:25'))
  263. self.assertEqual(datetime.time(14, 25, 59), f.clean('14:25:59'))
  264. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, 'hello')
  265. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '1:24 p.m.')
  266. def test_timefield_23(self):
  267. f = TimeField(input_formats=['%I:%M %p'])
  268. self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
  269. self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
  270. self.assertEqual(datetime.time(4, 25), f.clean('4:25 AM'))
  271. self.assertEqual(datetime.time(16, 25), f.clean('4:25 PM'))
  272. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '14:30:45')
  273. # DateTimeField ###############################################################
  274. def test_datetimefield_24(self):
  275. f = DateTimeField()
  276. self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25)))
  277. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
  278. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
  279. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
  280. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('2006-10-25 14:30:45'))
  281. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30:00'))
  282. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006-10-25 14:30'))
  283. self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('2006-10-25'))
  284. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/2006 14:30:45'))
  285. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30:00'))
  286. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/2006 14:30'))
  287. self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/2006'))
  288. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean('10/25/06 14:30:45'))
  289. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30:00'))
  290. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('10/25/06 14:30'))
  291. self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean('10/25/06'))
  292. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, 'hello')
  293. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 4:30 p.m.')
  294. def test_datetimefield_25(self):
  295. f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
  296. self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(datetime.date(2006, 10, 25)))
  297. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(datetime.datetime(2006, 10, 25, 14, 30)))
  298. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)))
  299. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 59, 200), f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)))
  300. self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean('2006 10 25 2:30 PM'))
  301. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date/time.']", f.clean, '2006-10-25 14:30:45')
  302. def test_datetimefield_26(self):
  303. f = DateTimeField(required=False)
  304. self.assertEqual(None, f.clean(None))
  305. self.assertEqual('None', repr(f.clean(None)))
  306. self.assertEqual(None, f.clean(''))
  307. self.assertEqual('None', repr(f.clean('')))
  308. # RegexField ##################################################################
  309. def test_regexfield_27(self):
  310. f = RegexField('^\d[A-F]\d$')
  311. self.assertEqual(u'2A2', f.clean('2A2'))
  312. self.assertEqual(u'3F3', f.clean('3F3'))
  313. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
  314. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2')
  315. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ')
  316. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  317. def test_regexfield_28(self):
  318. f = RegexField('^\d[A-F]\d$', required=False)
  319. self.assertEqual(u'2A2', f.clean('2A2'))
  320. self.assertEqual(u'3F3', f.clean('3F3'))
  321. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
  322. self.assertEqual(u'', f.clean(''))
  323. def test_regexfield_29(self):
  324. f = RegexField(re.compile('^\d[A-F]\d$'))
  325. self.assertEqual(u'2A2', f.clean('2A2'))
  326. self.assertEqual(u'3F3', f.clean('3F3'))
  327. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '3G3')
  328. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, ' 2A2')
  329. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '2A2 ')
  330. def test_regexfield_30(self):
  331. f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.')
  332. self.assertEqual(u'1234', f.clean('1234'))
  333. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, '123')
  334. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a four-digit number.']", f.clean, 'abcd')
  335. def test_regexfield_31(self):
  336. f = RegexField('^\d+$', min_length=5, max_length=10)
  337. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).']", f.clean, '123')
  338. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 5 characters (it has 3).', u'Enter a valid value.']", f.clean, 'abc')
  339. self.assertEqual(u'12345', f.clean('12345'))
  340. self.assertEqual(u'1234567890', f.clean('1234567890'))
  341. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 10 characters (it has 11).']", f.clean, '12345678901')
  342. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid value.']", f.clean, '12345a')
  343. # EmailField ##################################################################
  344. def test_emailfield_32(self):
  345. f = EmailField()
  346. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  347. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  348. self.assertEqual(u'person@example.com', f.clean('person@example.com'))
  349. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo')
  350. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@')
  351. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar')
  352. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@invalid-.com')
  353. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@-invalid.com')
  354. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.alid-.com')
  355. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.-alid.com')
  356. self.assertEqual(u'example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com'))
  357. self.assertEqual(u'example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com'))
  358. def test_email_regexp_for_performance(self):
  359. f = EmailField()
  360. # Check for runaway regex security problem. This will take for-freeking-ever
  361. # if the security fix isn't in place.
  362. self.assertRaisesErrorWithMessage(
  363. ValidationError,
  364. "[u'Enter a valid e-mail address.']",
  365. f.clean,
  366. 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058'
  367. )
  368. def test_emailfield_33(self):
  369. f = EmailField(required=False)
  370. self.assertEqual(u'', f.clean(''))
  371. self.assertEqual(u'', f.clean(None))
  372. self.assertEqual(u'person@example.com', f.clean('person@example.com'))
  373. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo')
  374. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@')
  375. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'foo@bar')
  376. def test_emailfield_34(self):
  377. f = EmailField(min_length=10, max_length=15)
  378. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 10 characters (it has 9).']", f.clean, 'a@foo.com')
  379. self.assertEqual(u'alf@foo.com', f.clean('alf@foo.com'))
  380. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 15 characters (it has 20).']", f.clean, 'alf123456788@foo.com')
  381. # FileField ##################################################################
  382. def test_filefield_35(self):
  383. f = FileField()
  384. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  385. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '', '')
  386. self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
  387. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  388. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None, '')
  389. self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
  390. self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''))
  391. self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''), '')
  392. self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf'))
  393. self.assertRaisesErrorWithMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, 'some content that is not a file')
  394. self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', None))
  395. self.assertRaisesErrorWithMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', ''))
  396. self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
  397. self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'))))
  398. self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'), 'files/test4.pdf')))
  399. def test_filefield_36(self):
  400. f = FileField(max_length = 5)
  401. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this filename has at most 5 characters (it has 18).']", f.clean, SimpleUploadedFile('test_maxlength.txt', 'hello world'))
  402. self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
  403. self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
  404. self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
  405. # URLField ##################################################################
  406. def test_urlfield_37(self):
  407. f = URLField()
  408. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  409. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  410. self.assertEqual(u'http://localhost/', f.clean('http://localhost'))
  411. self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
  412. self.assertEqual(u'http://example.com./', f.clean('http://example.com.'))
  413. self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com'))
  414. self.assertEqual(u'http://www.example.com:8000/test', f.clean('http://www.example.com:8000/test'))
  415. self.assertEqual(u'http://valid-with-hyphens.com/', f.clean('valid-with-hyphens.com'))
  416. self.assertEqual(u'http://subdomain.domain.com/', f.clean('subdomain.domain.com'))
  417. self.assertEqual(u'http://200.8.9.10/', f.clean('http://200.8.9.10'))
  418. self.assertEqual(u'http://200.8.9.10:8000/test', f.clean('http://200.8.9.10:8000/test'))
  419. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo')
  420. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://')
  421. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
  422. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.')
  423. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'com.')
  424. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, '.')
  425. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com')
  426. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://invalid-.com')
  427. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://-invalid.com')
  428. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.alid-.com')
  429. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com')
  430. self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com'))
  431. def test_url_regex_ticket11198(self):
  432. f = URLField()
  433. # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed
  434. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*200,))
  435. # a second test, to make sure the problem is really addressed, even on
  436. # domains that don't fail the domain label length check in the regex
  437. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,))
  438. def test_urlfield_38(self):
  439. f = URLField(required=False)
  440. self.assertEqual(u'', f.clean(''))
  441. self.assertEqual(u'', f.clean(None))
  442. self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
  443. self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com'))
  444. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'foo')
  445. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://')
  446. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
  447. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.')
  448. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com')
  449. def test_urlfield_39(self):
  450. f = URLField(verify_exists=True)
  451. self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection
  452. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example')
  453. self.assertRaises(ValidationError, f.clean, 'http://www.broken.djangoproject.com') # bad domain
  454. try:
  455. f.clean('http://www.broken.djangoproject.com') # bad domain
  456. except ValidationError, e:
  457. self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
  458. self.assertRaises(ValidationError, f.clean, 'http://google.com/we-love-microsoft.html') # good domain, bad page
  459. try:
  460. f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
  461. except ValidationError, e:
  462. self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
  463. def test_urlfield_40(self):
  464. f = URLField(verify_exists=True, required=False)
  465. self.assertEqual(u'', f.clean(''))
  466. self.assertEqual(u'http://www.google.com/', f.clean('http://www.google.com')) # This will fail if there's no Internet connection
  467. def test_urlfield_41(self):
  468. f = URLField(min_length=15, max_length=20)
  469. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at least 15 characters (it has 13).']", f.clean, 'http://f.com')
  470. self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
  471. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 38).']", f.clean, 'http://abcdefghijklmnopqrstuvwxyz.com')
  472. def test_urlfield_42(self):
  473. f = URLField(required=False)
  474. self.assertEqual(u'http://example.com/', f.clean('example.com'))
  475. self.assertEqual(u'', f.clean(''))
  476. self.assertEqual(u'https://example.com/', f.clean('https://example.com'))
  477. def test_urlfield_43(self):
  478. f = URLField()
  479. self.assertEqual(u'http://example.com/', f.clean('http://example.com'))
  480. self.assertEqual(u'http://example.com/test', f.clean('http://example.com/test'))
  481. def test_urlfield_ticket11826(self):
  482. f = URLField()
  483. self.assertEqual(u'http://example.com/?some_param=some_value', f.clean('http://example.com?some_param=some_value'))
  484. # BooleanField ################################################################
  485. def test_booleanfield_44(self):
  486. f = BooleanField()
  487. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  488. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  489. self.assertEqual(True, f.clean(True))
  490. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, False)
  491. self.assertEqual(True, f.clean(1))
  492. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 0)
  493. self.assertEqual(True, f.clean('Django rocks'))
  494. self.assertEqual(True, f.clean('True'))
  495. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, 'False')
  496. def test_booleanfield_45(self):
  497. f = BooleanField(required=False)
  498. self.assertEqual(False, f.clean(''))
  499. self.assertEqual(False, f.clean(None))
  500. self.assertEqual(True, f.clean(True))
  501. self.assertEqual(False, f.clean(False))
  502. self.assertEqual(True, f.clean(1))
  503. self.assertEqual(False, f.clean(0))
  504. self.assertEqual(True, f.clean('1'))
  505. self.assertEqual(False, f.clean('0'))
  506. self.assertEqual(True, f.clean('Django rocks'))
  507. self.assertEqual(False, f.clean('False'))
  508. # ChoiceField #################################################################
  509. def test_choicefield_46(self):
  510. f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')])
  511. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  512. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  513. self.assertEqual(u'1', f.clean(1))
  514. self.assertEqual(u'1', f.clean('1'))
  515. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3')
  516. def test_choicefield_47(self):
  517. f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
  518. self.assertEqual(u'', f.clean(''))
  519. self.assertEqual(u'', f.clean(None))
  520. self.assertEqual(u'1', f.clean(1))
  521. self.assertEqual(u'1', f.clean('1'))
  522. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, '3')
  523. def test_choicefield_48(self):
  524. f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
  525. self.assertEqual(u'J', f.clean('J'))
  526. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. John is not one of the available choices.']", f.clean, 'John')
  527. def test_choicefield_49(self):
  528. f = ChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')])
  529. self.assertEqual(u'1', f.clean(1))
  530. self.assertEqual(u'1', f.clean('1'))
  531. self.assertEqual(u'3', f.clean(3))
  532. self.assertEqual(u'3', f.clean('3'))
  533. self.assertEqual(u'5', f.clean(5))
  534. self.assertEqual(u'5', f.clean('5'))
  535. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, '6')
  536. # TypedChoiceField ############################################################
  537. # TypedChoiceField is just like ChoiceField, except that coerced types will
  538. # be returned:
  539. def test_typedchoicefield_50(self):
  540. f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
  541. self.assertEqual(1, f.clean('1'))
  542. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 2 is not one of the available choices.']", f.clean, '2')
  543. def test_typedchoicefield_51(self):
  544. # Different coercion, same validation.
  545. f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=float)
  546. self.assertEqual(1.0, f.clean('1'))
  547. def test_typedchoicefield_52(self):
  548. # This can also cause weirdness: be careful (bool(-1) == True, remember)
  549. f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=bool)
  550. self.assertEqual(True, f.clean('-1'))
  551. def test_typedchoicefield_53(self):
  552. # Even more weirdness: if you have a valid choice but your coercion function
  553. # can't coerce, you'll still get a validation error. Don't do this!
  554. f = TypedChoiceField(choices=[('A', 'A'), ('B', 'B')], coerce=int)
  555. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. B is not one of the available choices.']", f.clean, 'B')
  556. # Required fields require values
  557. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  558. def test_typedchoicefield_54(self):
  559. # Non-required fields aren't required
  560. f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False)
  561. self.assertEqual('', f.clean(''))
  562. # If you want cleaning an empty value to return a different type, tell the field
  563. def test_typedchoicefield_55(self):
  564. f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
  565. self.assertEqual(None, f.clean(''))
  566. # NullBooleanField ############################################################
  567. def test_nullbooleanfield_56(self):
  568. f = NullBooleanField()
  569. self.assertEqual(None, f.clean(''))
  570. self.assertEqual(True, f.clean(True))
  571. self.assertEqual(False, f.clean(False))
  572. self.assertEqual(None, f.clean(None))
  573. self.assertEqual(False, f.clean('0'))
  574. self.assertEqual(True, f.clean('1'))
  575. self.assertEqual(None, f.clean('2'))
  576. self.assertEqual(None, f.clean('3'))
  577. self.assertEqual(None, f.clean('hello'))
  578. def test_nullbooleanfield_57(self):
  579. # Make sure that the internal value is preserved if using HiddenInput (#7753)
  580. class HiddenNullBooleanForm(Form):
  581. hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
  582. hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
  583. f = HiddenNullBooleanForm()
  584. self.assertEqual('<input type="hidden" name="hidden_nullbool1" value="True" id="id_hidden_nullbool1" /><input type="hidden" name="hidden_nullbool2" value="False" id="id_hidden_nullbool2" />', str(f))
  585. def test_nullbooleanfield_58(self):
  586. class HiddenNullBooleanForm(Form):
  587. hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
  588. hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
  589. f = HiddenNullBooleanForm({ 'hidden_nullbool1': 'True', 'hidden_nullbool2': 'False' })
  590. self.assertEqual(None, f.full_clean())
  591. self.assertEqual(True, f.cleaned_data['hidden_nullbool1'])
  592. self.assertEqual(False, f.cleaned_data['hidden_nullbool2'])
  593. def test_nullbooleanfield_59(self):
  594. # Make sure we're compatible with MySQL, which uses 0 and 1 for its boolean
  595. # values. (#9609)
  596. NULLBOOL_CHOICES = (('1', 'Yes'), ('0', 'No'), ('', 'Unknown'))
  597. class MySQLNullBooleanForm(Form):
  598. nullbool0 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
  599. nullbool1 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
  600. nullbool2 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
  601. f = MySQLNullBooleanForm({ 'nullbool0': '1', 'nullbool1': '0', 'nullbool2': '' })
  602. self.assertEqual(None, f.full_clean())
  603. self.assertEqual(True, f.cleaned_data['nullbool0'])
  604. self.assertEqual(False, f.cleaned_data['nullbool1'])
  605. self.assertEqual(None, f.cleaned_data['nullbool2'])
  606. # MultipleChoiceField #########################################################
  607. def test_multiplechoicefield_60(self):
  608. f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')])
  609. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  610. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  611. self.assertEqual([u'1'], f.clean([1]))
  612. self.assertEqual([u'1'], f.clean(['1']))
  613. self.assertEqual([u'1', u'2'], f.clean(['1', '2']))
  614. self.assertEqual([u'1', u'2'], f.clean([1, '2']))
  615. self.assertEqual([u'1', u'2'], f.clean((1, '2')))
  616. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
  617. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, [])
  618. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ())
  619. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3'])
  620. def test_multiplechoicefield_61(self):
  621. f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
  622. self.assertEqual([], f.clean(''))
  623. self.assertEqual([], f.clean(None))
  624. self.assertEqual([u'1'], f.clean([1]))
  625. self.assertEqual([u'1'], f.clean(['1']))
  626. self.assertEqual([u'1', u'2'], f.clean(['1', '2']))
  627. self.assertEqual([u'1', u'2'], f.clean([1, '2']))
  628. self.assertEqual([u'1', u'2'], f.clean((1, '2')))
  629. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
  630. self.assertEqual([], f.clean([]))
  631. self.assertEqual([], f.clean(()))
  632. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 3 is not one of the available choices.']", f.clean, ['3'])
  633. def test_multiplechoicefield_62(self):
  634. f = MultipleChoiceField(choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3','A'),('4','B'))), ('5','Other')])
  635. self.assertEqual([u'1'], f.clean([1]))
  636. self.assertEqual([u'1'], f.clean(['1']))
  637. self.assertEqual([u'1', u'5'], f.clean([1, 5]))
  638. self.assertEqual([u'1', u'5'], f.clean([1, '5']))
  639. self.assertEqual([u'1', u'5'], f.clean(['1', 5]))
  640. self.assertEqual([u'1', u'5'], f.clean(['1', '5']))
  641. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['6'])
  642. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. 6 is not one of the available choices.']", f.clean, ['1','6'])
  643. # ComboField ##################################################################
  644. def test_combofield_63(self):
  645. f = ComboField(fields=[CharField(max_length=20), EmailField()])
  646. self.assertEqual(u'test@example.com', f.clean('test@example.com'))
  647. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 28).']", f.clean, 'longemailaddress@example.com')
  648. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'not an e-mail')
  649. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  650. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  651. def test_combofield_64(self):
  652. f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False)
  653. self.assertEqual(u'test@example.com', f.clean('test@example.com'))
  654. self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value has at most 20 characters (it has 28).']", f.clean, 'longemailaddress@example.com')
  655. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'not an e-mail')
  656. self.assertEqual(u'', f.clean(''))
  657. self.assertEqual(u'', f.clean(None))
  658. # FilePathField ###############################################################
  659. def test_filepathfield_65(self):
  660. path = forms.__file__
  661. path = os.path.dirname(path) + '/'
  662. assert fix_os_paths(path).endswith('/django/forms/')
  663. def test_filepathfield_66(self):
  664. path = forms.__file__
  665. path = os.path.dirname(path) + '/'
  666. f = FilePathField(path=path)
  667. f.choices = [p for p in f.choices if p[0].endswith('.py')]
  668. f.choices.sort()
  669. expected = [
  670. ('/django/forms/__init__.py', '__init__.py'),
  671. ('/django/forms/fields.py', 'fields.py'),
  672. ('/django/forms/forms.py', 'forms.py'),
  673. ('/django/forms/formsets.py', 'formsets.py'),
  674. ('/django/forms/models.py', 'models.py'),
  675. ('/django/forms/util.py', 'util.py'),
  676. ('/django/forms/widgets.py', 'widgets.py')
  677. ]
  678. for exp, got in zip(expected, fix_os_paths(f.choices)):
  679. self.assertEqual(exp[1], got[1])
  680. assert got[0].endswith(exp[0])
  681. self.assertRaisesErrorWithMessage(ValidationError, "[u'Select a valid choice. fields.py is not one of the available choices.']", f.clean, 'fields.py')
  682. assert fix_os_paths(f.clean(path + 'fields.py')).endswith('/django/forms/fields.py')
  683. def test_filepathfield_67(self):
  684. path = forms.__file__
  685. path = os.path.dirname(path) + '/'
  686. f = FilePathField(path=path, match='^.*?\.py$')
  687. f.choices.sort()
  688. expected = [
  689. ('/django/forms/__init__.py', '__init__.py'),
  690. ('/django/forms/fields.py', 'fields.py'),
  691. ('/django/forms/forms.py', 'forms.py'),
  692. ('/django/forms/formsets.py', 'formsets.py'),
  693. ('/django/forms/models.py', 'models.py'),
  694. ('/django/forms/util.py', 'util.py'),
  695. ('/django/forms/widgets.py', 'widgets.py')
  696. ]
  697. for exp, got in zip(expected, fix_os_paths(f.choices)):
  698. self.assertEqual(exp[1], got[1])
  699. assert got[0].endswith(exp[0])
  700. def test_filepathfield_68(self):
  701. path = forms.__file__
  702. path = os.path.dirname(path) + '/'
  703. f = FilePathField(path=path, recursive=True, match='^.*?\.py$')
  704. f.choices.sort()
  705. expected = [
  706. ('/django/forms/__init__.py', '__init__.py'),
  707. ('/django/forms/extras/__init__.py', 'extras/__init__.py'),
  708. ('/django/forms/extras/widgets.py', 'extras/widgets.py'),
  709. ('/django/forms/fields.py', 'fields.py'),
  710. ('/django/forms/forms.py', 'forms.py'),
  711. ('/django/forms/formsets.py', 'formsets.py'),
  712. ('/django/forms/models.py', 'models.py'),
  713. ('/django/forms/util.py', 'util.py'),
  714. ('/django/forms/widgets.py', 'widgets.py')
  715. ]
  716. for exp, got in zip(expected, fix_os_paths(f.choices)):
  717. self.assertEqual(exp[1], got[1])
  718. assert got[0].endswith(exp[0])
  719. # SplitDateTimeField ##########################################################
  720. def test_splitdatetimefield_69(self):
  721. from django.forms.widgets import SplitDateTimeWidget
  722. f = SplitDateTimeField()
  723. assert isinstance(f.widget, SplitDateTimeWidget)
  724. self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)]))
  725. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None)
  726. self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, '')
  727. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
  728. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.', u'Enter a valid time.']", f.clean, ['hello', 'there'])
  729. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', 'there'])
  730. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['hello', '07:30'])
  731. def test_splitdatetimefield_70(self):
  732. f = SplitDateTimeField(required=False)
  733. self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)]))
  734. self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean(['2006-01-10', '07:30']))
  735. self.assertEqual(None, f.clean(None))
  736. self.assertEqual(None, f.clean(''))
  737. self.assertEqual(None, f.clean(['']))
  738. self.assertEqual(None, f.clean(['', '']))
  739. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a list of values.']", f.clean, 'hello')
  740. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.', u'Enter a valid time.']", f.clean, ['hello', 'there'])
  741. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', 'there'])
  742. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['hello', '07:30'])
  743. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10', ''])
  744. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, ['2006-01-10'])
  745. self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, ['', '07:30'])