|
1 import datetime |
|
2 import unittest |
|
3 from decimal import Decimal |
|
4 |
|
5 import django.test |
|
6 from django import forms |
|
7 from django.db import models |
|
8 from django.core.exceptions import ValidationError |
|
9 |
|
10 from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, NullBooleanModel, BooleanModel |
|
11 |
|
12 # If PIL available, do these tests. |
|
13 if Image: |
|
14 from imagefield import \ |
|
15 ImageFieldTests, \ |
|
16 ImageFieldTwoDimensionsTests, \ |
|
17 ImageFieldNoDimensionsTests, \ |
|
18 ImageFieldOneDimensionTests, \ |
|
19 ImageFieldDimensionsFirstTests, \ |
|
20 ImageFieldUsingFileTests, \ |
|
21 TwoImageFieldTests |
|
22 |
|
23 |
|
24 class BasicFieldTests(django.test.TestCase): |
|
25 def test_show_hidden_initial(self): |
|
26 """ |
|
27 Regression test for #12913. Make sure fields with choices respect |
|
28 show_hidden_initial as a kwarg to models.Field.formfield() |
|
29 """ |
|
30 choices = [(0, 0), (1, 1)] |
|
31 model_field = models.Field(choices=choices) |
|
32 form_field = model_field.formfield(show_hidden_initial=True) |
|
33 self.assertTrue(form_field.show_hidden_initial) |
|
34 |
|
35 form_field = model_field.formfield(show_hidden_initial=False) |
|
36 self.assertFalse(form_field.show_hidden_initial) |
|
37 |
|
38 def test_nullbooleanfield_blank(self): |
|
39 """ |
|
40 Regression test for #13071: NullBooleanField should not throw |
|
41 a validation error when given a value of None. |
|
42 |
|
43 """ |
|
44 nullboolean = NullBooleanModel(nbfield=None) |
|
45 try: |
|
46 nullboolean.full_clean() |
|
47 except ValidationError, e: |
|
48 self.fail("NullBooleanField failed validation with value of None: %s" % e.messages) |
|
49 |
|
50 class DecimalFieldTests(django.test.TestCase): |
|
51 def test_to_python(self): |
|
52 f = models.DecimalField(max_digits=4, decimal_places=2) |
|
53 self.assertEqual(f.to_python(3), Decimal("3")) |
|
54 self.assertEqual(f.to_python("3.14"), Decimal("3.14")) |
|
55 self.assertRaises(ValidationError, f.to_python, "abc") |
|
56 |
|
57 def test_default(self): |
|
58 f = models.DecimalField(default=Decimal("0.00")) |
|
59 self.assertEqual(f.get_default(), Decimal("0.00")) |
|
60 |
|
61 def test_format(self): |
|
62 f = models.DecimalField(max_digits=5, decimal_places=1) |
|
63 self.assertEqual(f._format(f.to_python(2)), u'2.0') |
|
64 self.assertEqual(f._format(f.to_python('2.6')), u'2.6') |
|
65 self.assertEqual(f._format(None), None) |
|
66 |
|
67 def test_get_db_prep_lookup(self): |
|
68 from django.db import connection |
|
69 f = models.DecimalField(max_digits=5, decimal_places=1) |
|
70 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None]) |
|
71 |
|
72 def test_filter_with_strings(self): |
|
73 """ |
|
74 We should be able to filter decimal fields using strings (#8023) |
|
75 """ |
|
76 Foo.objects.create(id=1, a='abc', d=Decimal("12.34")) |
|
77 self.assertEqual(list(Foo.objects.filter(d=u'1.23')), []) |
|
78 |
|
79 def test_save_without_float_conversion(self): |
|
80 """ |
|
81 Ensure decimals don't go through a corrupting float conversion during |
|
82 save (#5079). |
|
83 """ |
|
84 bd = BigD(d="12.9") |
|
85 bd.save() |
|
86 bd = BigD.objects.get(pk=bd.pk) |
|
87 self.assertEqual(bd.d, Decimal("12.9")) |
|
88 |
|
89 def test_lookup_really_big_value(self): |
|
90 """ |
|
91 Ensure that really big values can be used in a filter statement, even |
|
92 with older Python versions. |
|
93 """ |
|
94 # This should not crash. That counts as a win for our purposes. |
|
95 Foo.objects.filter(d__gte=100000000000) |
|
96 |
|
97 class ForeignKeyTests(django.test.TestCase): |
|
98 def test_callable_default(self): |
|
99 """Test the use of a lazy callable for ForeignKey.default""" |
|
100 a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34")) |
|
101 b = Bar.objects.create(b="bcd") |
|
102 self.assertEqual(b.a, a) |
|
103 |
|
104 class DateTimeFieldTests(unittest.TestCase): |
|
105 def test_datetimefield_to_python_usecs(self): |
|
106 """DateTimeField.to_python should support usecs""" |
|
107 f = models.DateTimeField() |
|
108 self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'), |
|
109 datetime.datetime(2001, 1, 2, 3, 4, 5, 6)) |
|
110 self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'), |
|
111 datetime.datetime(2001, 1, 2, 3, 4, 5, 999999)) |
|
112 |
|
113 def test_timefield_to_python_usecs(self): |
|
114 """TimeField.to_python should support usecs""" |
|
115 f = models.TimeField() |
|
116 self.assertEqual(f.to_python('01:02:03.000004'), |
|
117 datetime.time(1, 2, 3, 4)) |
|
118 self.assertEqual(f.to_python('01:02:03.999999'), |
|
119 datetime.time(1, 2, 3, 999999)) |
|
120 |
|
121 class BooleanFieldTests(unittest.TestCase): |
|
122 def _test_get_db_prep_lookup(self, f): |
|
123 from django.db import connection |
|
124 self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True]) |
|
125 self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True]) |
|
126 self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True]) |
|
127 self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False]) |
|
128 self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False]) |
|
129 self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False]) |
|
130 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None]) |
|
131 |
|
132 def _test_to_python(self, f): |
|
133 self.assertTrue(f.to_python(1) is True) |
|
134 self.assertTrue(f.to_python(0) is False) |
|
135 |
|
136 def test_booleanfield_get_db_prep_lookup(self): |
|
137 self._test_get_db_prep_lookup(models.BooleanField()) |
|
138 |
|
139 def test_nullbooleanfield_get_db_prep_lookup(self): |
|
140 self._test_get_db_prep_lookup(models.NullBooleanField()) |
|
141 |
|
142 def test_booleanfield_to_python(self): |
|
143 self._test_to_python(models.BooleanField()) |
|
144 |
|
145 def test_nullbooleanfield_to_python(self): |
|
146 self._test_to_python(models.NullBooleanField()) |
|
147 |
|
148 def test_booleanfield_choices_blank(self): |
|
149 """ |
|
150 Test that BooleanField with choices and defaults doesn't generate a |
|
151 formfield with the blank option (#9640, #10549). |
|
152 """ |
|
153 choices = [(1, u'Si'), (2, 'No')] |
|
154 f = models.BooleanField(choices=choices, default=1, null=True) |
|
155 self.assertEqual(f.formfield().choices, [('', '---------')] + choices) |
|
156 |
|
157 f = models.BooleanField(choices=choices, default=1, null=False) |
|
158 self.assertEqual(f.formfield().choices, choices) |
|
159 |
|
160 def test_return_type(self): |
|
161 b = BooleanModel() |
|
162 b.bfield = True |
|
163 b.save() |
|
164 b2 = BooleanModel.objects.get(pk=b.pk) |
|
165 self.assertTrue(isinstance(b2.bfield, bool)) |
|
166 self.assertEqual(b2.bfield, True) |
|
167 |
|
168 b3 = BooleanModel() |
|
169 b3.bfield = False |
|
170 b3.save() |
|
171 b4 = BooleanModel.objects.get(pk=b3.pk) |
|
172 self.assertTrue(isinstance(b4.bfield, bool)) |
|
173 self.assertEqual(b4.bfield, False) |
|
174 |
|
175 b = NullBooleanModel() |
|
176 b.nbfield = True |
|
177 b.save() |
|
178 b2 = NullBooleanModel.objects.get(pk=b.pk) |
|
179 self.assertTrue(isinstance(b2.nbfield, bool)) |
|
180 self.assertEqual(b2.nbfield, True) |
|
181 |
|
182 b3 = NullBooleanModel() |
|
183 b3.nbfield = False |
|
184 b3.save() |
|
185 b4 = NullBooleanModel.objects.get(pk=b3.pk) |
|
186 self.assertTrue(isinstance(b4.nbfield, bool)) |
|
187 self.assertEqual(b4.nbfield, False) |
|
188 |
|
189 # http://code.djangoproject.com/ticket/13293 |
|
190 # Verify that when an extra clause exists, the boolean |
|
191 # conversions are applied with an offset |
|
192 b5 = BooleanModel.objects.all().extra( |
|
193 select={'string_length': 'LENGTH(string)'})[0] |
|
194 self.assertFalse(isinstance(b5.pk, bool)) |
|
195 |
|
196 class ChoicesTests(django.test.TestCase): |
|
197 def test_choices_and_field_display(self): |
|
198 """ |
|
199 Check that get_choices and get_flatchoices interact with |
|
200 get_FIELD_display to return the expected values (#7913). |
|
201 """ |
|
202 self.assertEqual(Whiz(c=1).get_c_display(), 'First') # A nested value |
|
203 self.assertEqual(Whiz(c=0).get_c_display(), 'Other') # A top level value |
|
204 self.assertEqual(Whiz(c=9).get_c_display(), 9) # Invalid value |
|
205 self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value |
|
206 self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value |
|
207 |
|
208 class SlugFieldTests(django.test.TestCase): |
|
209 def test_slugfield_max_length(self): |
|
210 """ |
|
211 Make sure SlugField honors max_length (#9706) |
|
212 """ |
|
213 bs = BigS.objects.create(s = 'slug'*50) |
|
214 bs = BigS.objects.get(pk=bs.pk) |
|
215 self.assertEqual(bs.s, 'slug'*50) |
|
216 |
|
217 |
|
218 class ValidationTest(django.test.TestCase): |
|
219 def test_charfield_raises_error_on_empty_string(self): |
|
220 f = models.CharField() |
|
221 self.assertRaises(ValidationError, f.clean, "", None) |
|
222 |
|
223 def test_charfield_cleans_empty_string_when_blank_true(self): |
|
224 f = models.CharField(blank=True) |
|
225 self.assertEqual('', f.clean('', None)) |
|
226 |
|
227 def test_integerfield_cleans_valid_string(self): |
|
228 f = models.IntegerField() |
|
229 self.assertEqual(2, f.clean('2', None)) |
|
230 |
|
231 def test_integerfield_raises_error_on_invalid_intput(self): |
|
232 f = models.IntegerField() |
|
233 self.assertRaises(ValidationError, f.clean, "a", None) |
|
234 |
|
235 def test_charfield_with_choices_cleans_valid_choice(self): |
|
236 f = models.CharField(max_length=1, choices=[('a','A'), ('b','B')]) |
|
237 self.assertEqual('a', f.clean('a', None)) |
|
238 |
|
239 def test_charfield_with_choices_raises_error_on_invalid_choice(self): |
|
240 f = models.CharField(choices=[('a','A'), ('b','B')]) |
|
241 self.assertRaises(ValidationError, f.clean, "not a", None) |
|
242 |
|
243 def test_choices_validation_supports_named_groups(self): |
|
244 f = models.IntegerField(choices=(('group',((10,'A'),(20,'B'))),(30,'C'))) |
|
245 self.assertEqual(10, f.clean(10, None)) |
|
246 |
|
247 def test_nullable_integerfield_raises_error_with_blank_false(self): |
|
248 f = models.IntegerField(null=True, blank=False) |
|
249 self.assertRaises(ValidationError, f.clean, None, None) |
|
250 |
|
251 def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self): |
|
252 f = models.IntegerField(null=True, blank=True) |
|
253 self.assertEqual(None, f.clean(None, None)) |
|
254 |
|
255 def test_integerfield_raises_error_on_empty_input(self): |
|
256 f = models.IntegerField(null=False) |
|
257 self.assertRaises(ValidationError, f.clean, None, None) |
|
258 self.assertRaises(ValidationError, f.clean, '', None) |
|
259 |
|
260 def test_charfield_raises_error_on_empty_input(self): |
|
261 f = models.CharField(null=False) |
|
262 self.assertRaises(ValidationError, f.clean, None, None) |
|
263 |
|
264 def test_datefield_cleans_date(self): |
|
265 f = models.DateField() |
|
266 self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', None)) |
|
267 |
|
268 def test_boolean_field_doesnt_accept_empty_input(self): |
|
269 f = models.BooleanField() |
|
270 self.assertRaises(ValidationError, f.clean, None, None) |
|
271 |
|
272 |
|
273 class BigIntegerFieldTests(django.test.TestCase): |
|
274 def test_limits(self): |
|
275 # Ensure that values that are right at the limits can be saved |
|
276 # and then retrieved without corruption. |
|
277 maxval = 9223372036854775807 |
|
278 minval = -maxval - 1 |
|
279 BigInt.objects.create(value=maxval) |
|
280 qs = BigInt.objects.filter(value__gte=maxval) |
|
281 self.assertEqual(qs.count(), 1) |
|
282 self.assertEqual(qs[0].value, maxval) |
|
283 BigInt.objects.create(value=minval) |
|
284 qs = BigInt.objects.filter(value__lte=minval) |
|
285 self.assertEqual(qs.count(), 1) |
|
286 self.assertEqual(qs[0].value, minval) |
|
287 |
|
288 def test_types(self): |
|
289 b = BigInt(value = 0) |
|
290 self.assertTrue(isinstance(b.value, (int, long))) |
|
291 b.save() |
|
292 self.assertTrue(isinstance(b.value, (int, long))) |
|
293 b = BigInt.objects.all()[0] |
|
294 self.assertTrue(isinstance(b.value, (int, long))) |
|
295 |
|
296 def test_coercing(self): |
|
297 BigInt.objects.create(value ='10') |
|
298 b = BigInt.objects.get(value = '10') |
|
299 self.assertEqual(b.value, 10) |
|
300 |
|
301 class TypeCoercionTests(django.test.TestCase): |
|
302 """ |
|
303 Test that database lookups can accept the wrong types and convert |
|
304 them with no error: especially on Postgres 8.3+ which does not do |
|
305 automatic casting at the DB level. See #10015. |
|
306 |
|
307 """ |
|
308 def test_lookup_integer_in_charfield(self): |
|
309 self.assertEquals(Post.objects.filter(title=9).count(), 0) |
|
310 |
|
311 def test_lookup_integer_in_textfield(self): |
|
312 self.assertEquals(Post.objects.filter(body=24).count(), 0) |
|
313 |