App Engine Python SDK version 1.9.12
[gae.git] / python / lib / django-1.2 / tests / regressiontests / model_fields / tests.py
blob72a7d4d6579b18e2da07169f0ec3bb724b0df028
1 import datetime
2 import unittest
3 from decimal import Decimal
5 import django.test
6 from django import forms
7 from django.db import models
8 from django.core.exceptions import ValidationError
10 from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, NullBooleanModel, BooleanModel
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
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)
35 form_field = model_field.formfield(show_hidden_initial=False)
36 self.assertFalse(form_field.show_hidden_initial)
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.
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)
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")
57 def test_default(self):
58 f = models.DecimalField(default=Decimal("0.00"))
59 self.assertEqual(f.get_default(), Decimal("0.00"))
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)
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])
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')), [])
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"))
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)
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)
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))
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))
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])
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)
136 def test_booleanfield_get_db_prep_lookup(self):
137 self._test_get_db_prep_lookup(models.BooleanField())
139 def test_nullbooleanfield_get_db_prep_lookup(self):
140 self._test_get_db_prep_lookup(models.NullBooleanField())
142 def test_booleanfield_to_python(self):
143 self._test_to_python(models.BooleanField())
145 def test_nullbooleanfield_to_python(self):
146 self._test_to_python(models.NullBooleanField())
148 def test_booleanfield_choices_blank(self):
150 Test that BooleanField with choices and defaults doesn't generate a
151 formfield with the blank option (#9640, #10549).
153 choices = [(1, u'Si'), (2, 'No')]
154 f = models.BooleanField(choices=choices, default=1, null=True)
155 self.assertEqual(f.formfield().choices, [('', '---------')] + choices)
157 f = models.BooleanField(choices=choices, default=1, null=False)
158 self.assertEqual(f.formfield().choices, choices)
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)
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)
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)
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)
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))
196 class ChoicesTests(django.test.TestCase):
197 def test_choices_and_field_display(self):
199 Check that get_choices and get_flatchoices interact with
200 get_FIELD_display to return the expected values (#7913).
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
208 class SlugFieldTests(django.test.TestCase):
209 def test_slugfield_max_length(self):
211 Make sure SlugField honors max_length (#9706)
213 bs = BigS.objects.create(s = 'slug'*50)
214 bs = BigS.objects.get(pk=bs.pk)
215 self.assertEqual(bs.s, 'slug'*50)
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)
223 def test_charfield_cleans_empty_string_when_blank_true(self):
224 f = models.CharField(blank=True)
225 self.assertEqual('', f.clean('', None))
227 def test_integerfield_cleans_valid_string(self):
228 f = models.IntegerField()
229 self.assertEqual(2, f.clean('2', None))
231 def test_integerfield_raises_error_on_invalid_intput(self):
232 f = models.IntegerField()
233 self.assertRaises(ValidationError, f.clean, "a", None)
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))
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)
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))
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)
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))
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)
260 def test_charfield_raises_error_on_empty_input(self):
261 f = models.CharField(null=False)
262 self.assertRaises(ValidationError, f.clean, None, None)
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))
268 def test_boolean_field_doesnt_accept_empty_input(self):
269 f = models.BooleanField()
270 self.assertRaises(ValidationError, f.clean, None, None)
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)
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)))
296 def test_coercing(self):
297 BigInt.objects.create(value ='10')
298 b = BigInt.objects.get(value = '10')
299 self.assertEqual(b.value, 10)
301 class TypeCoercionTests(django.test.TestCase):
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.
308 def test_lookup_integer_in_charfield(self):
309 self.assertEquals(Post.objects.filter(title=9).count(), 0)
311 def test_lookup_integer_in_textfield(self):
312 self.assertEquals(Post.objects.filter(body=24).count(), 0)