App Engine Python SDK version 1.8.0
[gae.git] / python / lib / django-1.5 / tests / regressiontests / model_fields / tests.py
bloba49894e36ceadc8c0508435acf5ec4d745138dd5
1 from __future__ import absolute_import, unicode_literals
3 import datetime
4 from decimal import Decimal
6 from django import test
7 from django import forms
8 from django.core.exceptions import ValidationError
9 from django.db import models
10 from django.db.models.fields.files import FieldFile
11 from django.utils import six
12 from django.utils import unittest
14 from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
15 NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField,
16 FksToBooleans)
18 from .imagefield import (ImageFieldTests, ImageFieldTwoDimensionsTests,
19 TwoImageFieldTests, ImageFieldNoDimensionsTests,
20 ImageFieldOneDimensionTests, ImageFieldDimensionsFirstTests,
21 ImageFieldUsingFileTests)
24 class BasicFieldTests(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 as e:
48 self.fail("NullBooleanField failed validation with value of None: %s" % e.messages)
50 def test_field_repr(self):
51 """
52 Regression test for #5931: __repr__ of a field also displays its name
53 """
54 f = Foo._meta.get_field('a')
55 self.assertEqual(repr(f), '<django.db.models.fields.CharField: a>')
56 f = models.fields.CharField()
57 self.assertEqual(repr(f), '<django.db.models.fields.CharField>')
59 def test_field_name(self):
60 """
61 Regression test for #14695: explicitly defined field name overwritten
62 by model's attribute name.
63 """
64 instance = RenamedField()
65 self.assertTrue(hasattr(instance, 'get_fieldname_display'))
66 self.assertFalse(hasattr(instance, 'get_modelname_display'))
68 def test_field_verbose_name(self):
69 m = VerboseNameField
70 for i in range(1, 23):
71 self.assertEqual(m._meta.get_field('field%d' % i).verbose_name,
72 'verbose field%d' % i)
74 self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk')
76 class DecimalFieldTests(test.TestCase):
77 def test_to_python(self):
78 f = models.DecimalField(max_digits=4, decimal_places=2)
79 self.assertEqual(f.to_python(3), Decimal("3"))
80 self.assertEqual(f.to_python("3.14"), Decimal("3.14"))
81 self.assertRaises(ValidationError, f.to_python, "abc")
83 def test_default(self):
84 f = models.DecimalField(default=Decimal("0.00"))
85 self.assertEqual(f.get_default(), Decimal("0.00"))
87 def test_format(self):
88 f = models.DecimalField(max_digits=5, decimal_places=1)
89 self.assertEqual(f._format(f.to_python(2)), '2.0')
90 self.assertEqual(f._format(f.to_python('2.6')), '2.6')
91 self.assertEqual(f._format(None), None)
93 def test_get_db_prep_lookup(self):
94 from django.db import connection
95 f = models.DecimalField(max_digits=5, decimal_places=1)
96 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
98 def test_filter_with_strings(self):
99 """
100 We should be able to filter decimal fields using strings (#8023)
102 Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
103 self.assertEqual(list(Foo.objects.filter(d='1.23')), [])
105 def test_save_without_float_conversion(self):
107 Ensure decimals don't go through a corrupting float conversion during
108 save (#5079).
110 bd = BigD(d="12.9")
111 bd.save()
112 bd = BigD.objects.get(pk=bd.pk)
113 self.assertEqual(bd.d, Decimal("12.9"))
115 def test_lookup_really_big_value(self):
117 Ensure that really big values can be used in a filter statement, even
118 with older Python versions.
120 # This should not crash. That counts as a win for our purposes.
121 Foo.objects.filter(d__gte=100000000000)
123 class ForeignKeyTests(test.TestCase):
124 def test_callable_default(self):
125 """Test the use of a lazy callable for ForeignKey.default"""
126 a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
127 b = Bar.objects.create(b="bcd")
128 self.assertEqual(b.a, a)
130 class DateTimeFieldTests(unittest.TestCase):
131 def test_datetimefield_to_python_usecs(self):
132 """DateTimeField.to_python should support usecs"""
133 f = models.DateTimeField()
134 self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'),
135 datetime.datetime(2001, 1, 2, 3, 4, 5, 6))
136 self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'),
137 datetime.datetime(2001, 1, 2, 3, 4, 5, 999999))
139 def test_timefield_to_python_usecs(self):
140 """TimeField.to_python should support usecs"""
141 f = models.TimeField()
142 self.assertEqual(f.to_python('01:02:03.000004'),
143 datetime.time(1, 2, 3, 4))
144 self.assertEqual(f.to_python('01:02:03.999999'),
145 datetime.time(1, 2, 3, 999999))
147 class BooleanFieldTests(unittest.TestCase):
148 def _test_get_db_prep_lookup(self, f):
149 from django.db import connection
150 self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True])
151 self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True])
152 self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True])
153 self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False])
154 self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False])
155 self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
156 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
158 def _test_to_python(self, f):
159 self.assertTrue(f.to_python(1) is True)
160 self.assertTrue(f.to_python(0) is False)
162 def test_booleanfield_get_db_prep_lookup(self):
163 self._test_get_db_prep_lookup(models.BooleanField())
165 def test_nullbooleanfield_get_db_prep_lookup(self):
166 self._test_get_db_prep_lookup(models.NullBooleanField())
168 def test_booleanfield_to_python(self):
169 self._test_to_python(models.BooleanField())
171 def test_nullbooleanfield_to_python(self):
172 self._test_to_python(models.NullBooleanField())
174 def test_booleanfield_choices_blank(self):
176 Test that BooleanField with choices and defaults doesn't generate a
177 formfield with the blank option (#9640, #10549).
179 choices = [(1, 'Si'), (2, 'No')]
180 f = models.BooleanField(choices=choices, default=1, null=True)
181 self.assertEqual(f.formfield().choices, [('', '---------')] + choices)
183 f = models.BooleanField(choices=choices, default=1, null=False)
184 self.assertEqual(f.formfield().choices, choices)
186 def test_return_type(self):
187 b = BooleanModel()
188 b.bfield = True
189 b.save()
190 b2 = BooleanModel.objects.get(pk=b.pk)
191 self.assertTrue(isinstance(b2.bfield, bool))
192 self.assertEqual(b2.bfield, True)
194 b3 = BooleanModel()
195 b3.bfield = False
196 b3.save()
197 b4 = BooleanModel.objects.get(pk=b3.pk)
198 self.assertTrue(isinstance(b4.bfield, bool))
199 self.assertEqual(b4.bfield, False)
201 b = NullBooleanModel()
202 b.nbfield = True
203 b.save()
204 b2 = NullBooleanModel.objects.get(pk=b.pk)
205 self.assertTrue(isinstance(b2.nbfield, bool))
206 self.assertEqual(b2.nbfield, True)
208 b3 = NullBooleanModel()
209 b3.nbfield = False
210 b3.save()
211 b4 = NullBooleanModel.objects.get(pk=b3.pk)
212 self.assertTrue(isinstance(b4.nbfield, bool))
213 self.assertEqual(b4.nbfield, False)
215 # http://code.djangoproject.com/ticket/13293
216 # Verify that when an extra clause exists, the boolean
217 # conversions are applied with an offset
218 b5 = BooleanModel.objects.all().extra(
219 select={'string_col': 'string'})[0]
220 self.assertFalse(isinstance(b5.pk, bool))
222 def test_select_related(self):
224 Test type of boolean fields when retrieved via select_related() (MySQL,
225 #15040)
227 bmt = BooleanModel.objects.create(bfield=True)
228 bmf = BooleanModel.objects.create(bfield=False)
229 nbmt = NullBooleanModel.objects.create(nbfield=True)
230 nbmf = NullBooleanModel.objects.create(nbfield=False)
232 m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
233 m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
235 # Test select_related('fk_field_name')
236 ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
237 # verify types -- should't be 0/1
238 self.assertIsInstance(ma.bf.bfield, bool)
239 self.assertIsInstance(ma.nbf.nbfield, bool)
240 # verify values
241 self.assertEqual(ma.bf.bfield, True)
242 self.assertEqual(ma.nbf.nbfield, True)
244 # Test select_related()
245 mb = FksToBooleans.objects.select_related().get(pk=m1.id)
246 mc = FksToBooleans.objects.select_related().get(pk=m2.id)
247 # verify types -- shouldn't be 0/1
248 self.assertIsInstance(mb.bf.bfield, bool)
249 self.assertIsInstance(mb.nbf.nbfield, bool)
250 self.assertIsInstance(mc.bf.bfield, bool)
251 self.assertIsInstance(mc.nbf.nbfield, bool)
252 # verify values
253 self.assertEqual(mb.bf.bfield, True)
254 self.assertEqual(mb.nbf.nbfield, True)
255 self.assertEqual(mc.bf.bfield, False)
256 self.assertEqual(mc.nbf.nbfield, False)
259 class ChoicesTests(test.TestCase):
260 def test_choices_and_field_display(self):
262 Check that get_choices and get_flatchoices interact with
263 get_FIELD_display to return the expected values (#7913).
265 self.assertEqual(Whiz(c=1).get_c_display(), 'First') # A nested value
266 self.assertEqual(Whiz(c=0).get_c_display(), 'Other') # A top level value
267 self.assertEqual(Whiz(c=9).get_c_display(), 9) # Invalid value
268 self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value
269 self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value
271 class SlugFieldTests(test.TestCase):
272 def test_slugfield_max_length(self):
274 Make sure SlugField honors max_length (#9706)
276 bs = BigS.objects.create(s = 'slug'*50)
277 bs = BigS.objects.get(pk=bs.pk)
278 self.assertEqual(bs.s, 'slug'*50)
281 class ValidationTest(test.TestCase):
282 def test_charfield_raises_error_on_empty_string(self):
283 f = models.CharField()
284 self.assertRaises(ValidationError, f.clean, "", None)
286 def test_charfield_cleans_empty_string_when_blank_true(self):
287 f = models.CharField(blank=True)
288 self.assertEqual('', f.clean('', None))
290 def test_integerfield_cleans_valid_string(self):
291 f = models.IntegerField()
292 self.assertEqual(2, f.clean('2', None))
294 def test_integerfield_raises_error_on_invalid_intput(self):
295 f = models.IntegerField()
296 self.assertRaises(ValidationError, f.clean, "a", None)
298 def test_charfield_with_choices_cleans_valid_choice(self):
299 f = models.CharField(max_length=1, choices=[('a','A'), ('b','B')])
300 self.assertEqual('a', f.clean('a', None))
302 def test_charfield_with_choices_raises_error_on_invalid_choice(self):
303 f = models.CharField(choices=[('a','A'), ('b','B')])
304 self.assertRaises(ValidationError, f.clean, "not a", None)
306 def test_choices_validation_supports_named_groups(self):
307 f = models.IntegerField(choices=(('group',((10,'A'),(20,'B'))),(30,'C')))
308 self.assertEqual(10, f.clean(10, None))
310 def test_nullable_integerfield_raises_error_with_blank_false(self):
311 f = models.IntegerField(null=True, blank=False)
312 self.assertRaises(ValidationError, f.clean, None, None)
314 def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self):
315 f = models.IntegerField(null=True, blank=True)
316 self.assertEqual(None, f.clean(None, None))
318 def test_integerfield_raises_error_on_empty_input(self):
319 f = models.IntegerField(null=False)
320 self.assertRaises(ValidationError, f.clean, None, None)
321 self.assertRaises(ValidationError, f.clean, '', None)
323 def test_integerfield_validates_zero_against_choices(self):
324 f = models.IntegerField(choices=((1, 1),))
325 self.assertRaises(ValidationError, f.clean, '0', None)
327 def test_charfield_raises_error_on_empty_input(self):
328 f = models.CharField(null=False)
329 self.assertRaises(ValidationError, f.clean, None, None)
331 def test_datefield_cleans_date(self):
332 f = models.DateField()
333 self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', None))
335 def test_boolean_field_doesnt_accept_empty_input(self):
336 f = models.BooleanField()
337 self.assertRaises(ValidationError, f.clean, None, None)
340 class BigIntegerFieldTests(test.TestCase):
341 def test_limits(self):
342 # Ensure that values that are right at the limits can be saved
343 # and then retrieved without corruption.
344 maxval = 9223372036854775807
345 minval = -maxval - 1
346 BigInt.objects.create(value=maxval)
347 qs = BigInt.objects.filter(value__gte=maxval)
348 self.assertEqual(qs.count(), 1)
349 self.assertEqual(qs[0].value, maxval)
350 BigInt.objects.create(value=minval)
351 qs = BigInt.objects.filter(value__lte=minval)
352 self.assertEqual(qs.count(), 1)
353 self.assertEqual(qs[0].value, minval)
355 def test_types(self):
356 b = BigInt(value = 0)
357 self.assertTrue(isinstance(b.value, six.integer_types))
358 b.save()
359 self.assertTrue(isinstance(b.value, six.integer_types))
360 b = BigInt.objects.all()[0]
361 self.assertTrue(isinstance(b.value, six.integer_types))
363 def test_coercing(self):
364 BigInt.objects.create(value ='10')
365 b = BigInt.objects.get(value = '10')
366 self.assertEqual(b.value, 10)
368 class TypeCoercionTests(test.TestCase):
370 Test that database lookups can accept the wrong types and convert
371 them with no error: especially on Postgres 8.3+ which does not do
372 automatic casting at the DB level. See #10015.
375 def test_lookup_integer_in_charfield(self):
376 self.assertEqual(Post.objects.filter(title=9).count(), 0)
378 def test_lookup_integer_in_textfield(self):
379 self.assertEqual(Post.objects.filter(body=24).count(), 0)
381 class FileFieldTests(unittest.TestCase):
382 def test_clearable(self):
384 Test that FileField.save_form_data will clear its instance attribute
385 value if passed False.
388 d = Document(myfile='something.txt')
389 self.assertEqual(d.myfile, 'something.txt')
390 field = d._meta.get_field('myfile')
391 field.save_form_data(d, False)
392 self.assertEqual(d.myfile, '')
394 def test_unchanged(self):
396 Test that FileField.save_form_data considers None to mean "no change"
397 rather than "clear".
400 d = Document(myfile='something.txt')
401 self.assertEqual(d.myfile, 'something.txt')
402 field = d._meta.get_field('myfile')
403 field.save_form_data(d, None)
404 self.assertEqual(d.myfile, 'something.txt')
406 def test_changed(self):
408 Test that FileField.save_form_data, if passed a truthy value, updates
409 its instance attribute.
412 d = Document(myfile='something.txt')
413 self.assertEqual(d.myfile, 'something.txt')
414 field = d._meta.get_field('myfile')
415 field.save_form_data(d, 'else.txt')
416 self.assertEqual(d.myfile, 'else.txt')