1.9.30 sync.
[gae.git] / python / lib / django-1.5 / tests / regressiontests / model_fields / tests.py
blob5fd4db1dcd4d582f91100a9acb6c28c58add185e
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.models.fields import (
10 AutoField, BigIntegerField, BooleanField, CharField,
11 CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField,
12 EmailField, FilePathField, FloatField, IntegerField, IPAddressField,
13 GenericIPAddressField, NullBooleanField, PositiveIntegerField,
14 PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField,
15 TimeField, URLField)
16 from django.db import models
17 from django.db.models.fields.files import FileField, ImageField, FieldFile
18 from django.utils import six
19 from django.utils import unittest
21 from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
22 NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField,
23 FksToBooleans)
25 from .imagefield import (ImageFieldTests, ImageFieldTwoDimensionsTests,
26 TwoImageFieldTests, ImageFieldNoDimensionsTests,
27 ImageFieldOneDimensionTests, ImageFieldDimensionsFirstTests,
28 ImageFieldUsingFileTests)
31 class BasicFieldTests(test.TestCase):
32 def test_show_hidden_initial(self):
33 """
34 Regression test for #12913. Make sure fields with choices respect
35 show_hidden_initial as a kwarg to models.Field.formfield()
36 """
37 choices = [(0, 0), (1, 1)]
38 model_field = models.Field(choices=choices)
39 form_field = model_field.formfield(show_hidden_initial=True)
40 self.assertTrue(form_field.show_hidden_initial)
42 form_field = model_field.formfield(show_hidden_initial=False)
43 self.assertFalse(form_field.show_hidden_initial)
45 def test_nullbooleanfield_blank(self):
46 """
47 Regression test for #13071: NullBooleanField should not throw
48 a validation error when given a value of None.
50 """
51 nullboolean = NullBooleanModel(nbfield=None)
52 try:
53 nullboolean.full_clean()
54 except ValidationError as e:
55 self.fail("NullBooleanField failed validation with value of None: %s" % e.messages)
57 def test_field_repr(self):
58 """
59 Regression test for #5931: __repr__ of a field also displays its name
60 """
61 f = Foo._meta.get_field('a')
62 self.assertEqual(repr(f), '<django.db.models.fields.CharField: a>')
63 f = models.fields.CharField()
64 self.assertEqual(repr(f), '<django.db.models.fields.CharField>')
66 def test_field_name(self):
67 """
68 Regression test for #14695: explicitly defined field name overwritten
69 by model's attribute name.
70 """
71 instance = RenamedField()
72 self.assertTrue(hasattr(instance, 'get_fieldname_display'))
73 self.assertFalse(hasattr(instance, 'get_modelname_display'))
75 def test_field_verbose_name(self):
76 m = VerboseNameField
77 for i in range(1, 23):
78 self.assertEqual(m._meta.get_field('field%d' % i).verbose_name,
79 'verbose field%d' % i)
81 self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk')
83 class DecimalFieldTests(test.TestCase):
84 def test_to_python(self):
85 f = models.DecimalField(max_digits=4, decimal_places=2)
86 self.assertEqual(f.to_python(3), Decimal("3"))
87 self.assertEqual(f.to_python("3.14"), Decimal("3.14"))
88 self.assertRaises(ValidationError, f.to_python, "abc")
90 def test_default(self):
91 f = models.DecimalField(default=Decimal("0.00"))
92 self.assertEqual(f.get_default(), Decimal("0.00"))
94 def test_format(self):
95 f = models.DecimalField(max_digits=5, decimal_places=1)
96 self.assertEqual(f._format(f.to_python(2)), '2.0')
97 self.assertEqual(f._format(f.to_python('2.6')), '2.6')
98 self.assertEqual(f._format(None), None)
100 def test_get_db_prep_lookup(self):
101 from django.db import connection
102 f = models.DecimalField(max_digits=5, decimal_places=1)
103 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
105 def test_filter_with_strings(self):
107 We should be able to filter decimal fields using strings (#8023)
109 Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
110 self.assertEqual(list(Foo.objects.filter(d='1.23')), [])
112 def test_save_without_float_conversion(self):
114 Ensure decimals don't go through a corrupting float conversion during
115 save (#5079).
117 bd = BigD(d="12.9")
118 bd.save()
119 bd = BigD.objects.get(pk=bd.pk)
120 self.assertEqual(bd.d, Decimal("12.9"))
122 def test_lookup_really_big_value(self):
124 Ensure that really big values can be used in a filter statement, even
125 with older Python versions.
127 # This should not crash. That counts as a win for our purposes.
128 Foo.objects.filter(d__gte=100000000000)
130 class ForeignKeyTests(test.TestCase):
131 def test_callable_default(self):
132 """Test the use of a lazy callable for ForeignKey.default"""
133 a = Foo.objects.create(id=1, a='abc', d=Decimal("12.34"))
134 b = Bar.objects.create(b="bcd")
135 self.assertEqual(b.a, a)
137 class DateTimeFieldTests(unittest.TestCase):
138 def test_datetimefield_to_python_usecs(self):
139 """DateTimeField.to_python should support usecs"""
140 f = models.DateTimeField()
141 self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'),
142 datetime.datetime(2001, 1, 2, 3, 4, 5, 6))
143 self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'),
144 datetime.datetime(2001, 1, 2, 3, 4, 5, 999999))
146 def test_timefield_to_python_usecs(self):
147 """TimeField.to_python should support usecs"""
148 f = models.TimeField()
149 self.assertEqual(f.to_python('01:02:03.000004'),
150 datetime.time(1, 2, 3, 4))
151 self.assertEqual(f.to_python('01:02:03.999999'),
152 datetime.time(1, 2, 3, 999999))
154 class BooleanFieldTests(unittest.TestCase):
155 def _test_get_db_prep_lookup(self, f):
156 from django.db import connection
157 self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True])
158 self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True])
159 self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True])
160 self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False])
161 self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False])
162 self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
163 self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
165 def _test_to_python(self, f):
166 self.assertTrue(f.to_python(1) is True)
167 self.assertTrue(f.to_python(0) is False)
169 def test_booleanfield_get_db_prep_lookup(self):
170 self._test_get_db_prep_lookup(models.BooleanField())
172 def test_nullbooleanfield_get_db_prep_lookup(self):
173 self._test_get_db_prep_lookup(models.NullBooleanField())
175 def test_booleanfield_to_python(self):
176 self._test_to_python(models.BooleanField())
178 def test_nullbooleanfield_to_python(self):
179 self._test_to_python(models.NullBooleanField())
181 def test_booleanfield_choices_blank(self):
183 Test that BooleanField with choices and defaults doesn't generate a
184 formfield with the blank option (#9640, #10549).
186 choices = [(1, 'Si'), (2, 'No')]
187 f = models.BooleanField(choices=choices, default=1, null=True)
188 self.assertEqual(f.formfield().choices, [('', '---------')] + choices)
190 f = models.BooleanField(choices=choices, default=1, null=False)
191 self.assertEqual(f.formfield().choices, choices)
193 def test_return_type(self):
194 b = BooleanModel()
195 b.bfield = True
196 b.save()
197 b2 = BooleanModel.objects.get(pk=b.pk)
198 self.assertTrue(isinstance(b2.bfield, bool))
199 self.assertEqual(b2.bfield, True)
201 b3 = BooleanModel()
202 b3.bfield = False
203 b3.save()
204 b4 = BooleanModel.objects.get(pk=b3.pk)
205 self.assertTrue(isinstance(b4.bfield, bool))
206 self.assertEqual(b4.bfield, False)
208 b = NullBooleanModel()
209 b.nbfield = True
210 b.save()
211 b2 = NullBooleanModel.objects.get(pk=b.pk)
212 self.assertTrue(isinstance(b2.nbfield, bool))
213 self.assertEqual(b2.nbfield, True)
215 b3 = NullBooleanModel()
216 b3.nbfield = False
217 b3.save()
218 b4 = NullBooleanModel.objects.get(pk=b3.pk)
219 self.assertTrue(isinstance(b4.nbfield, bool))
220 self.assertEqual(b4.nbfield, False)
222 # http://code.djangoproject.com/ticket/13293
223 # Verify that when an extra clause exists, the boolean
224 # conversions are applied with an offset
225 b5 = BooleanModel.objects.all().extra(
226 select={'string_col': 'string'})[0]
227 self.assertFalse(isinstance(b5.pk, bool))
229 def test_select_related(self):
231 Test type of boolean fields when retrieved via select_related() (MySQL,
232 #15040)
234 bmt = BooleanModel.objects.create(bfield=True)
235 bmf = BooleanModel.objects.create(bfield=False)
236 nbmt = NullBooleanModel.objects.create(nbfield=True)
237 nbmf = NullBooleanModel.objects.create(nbfield=False)
239 m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
240 m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
242 # Test select_related('fk_field_name')
243 ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
244 # verify types -- should't be 0/1
245 self.assertIsInstance(ma.bf.bfield, bool)
246 self.assertIsInstance(ma.nbf.nbfield, bool)
247 # verify values
248 self.assertEqual(ma.bf.bfield, True)
249 self.assertEqual(ma.nbf.nbfield, True)
251 # Test select_related()
252 mb = FksToBooleans.objects.select_related().get(pk=m1.id)
253 mc = FksToBooleans.objects.select_related().get(pk=m2.id)
254 # verify types -- shouldn't be 0/1
255 self.assertIsInstance(mb.bf.bfield, bool)
256 self.assertIsInstance(mb.nbf.nbfield, bool)
257 self.assertIsInstance(mc.bf.bfield, bool)
258 self.assertIsInstance(mc.nbf.nbfield, bool)
259 # verify values
260 self.assertEqual(mb.bf.bfield, True)
261 self.assertEqual(mb.nbf.nbfield, True)
262 self.assertEqual(mc.bf.bfield, False)
263 self.assertEqual(mc.nbf.nbfield, False)
266 class ChoicesTests(test.TestCase):
267 def test_choices_and_field_display(self):
269 Check that get_choices and get_flatchoices interact with
270 get_FIELD_display to return the expected values (#7913).
272 self.assertEqual(Whiz(c=1).get_c_display(), 'First') # A nested value
273 self.assertEqual(Whiz(c=0).get_c_display(), 'Other') # A top level value
274 self.assertEqual(Whiz(c=9).get_c_display(), 9) # Invalid value
275 self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value
276 self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value
278 class SlugFieldTests(test.TestCase):
279 def test_slugfield_max_length(self):
281 Make sure SlugField honors max_length (#9706)
283 bs = BigS.objects.create(s = 'slug'*50)
284 bs = BigS.objects.get(pk=bs.pk)
285 self.assertEqual(bs.s, 'slug'*50)
288 class ValidationTest(test.TestCase):
289 def test_charfield_raises_error_on_empty_string(self):
290 f = models.CharField()
291 self.assertRaises(ValidationError, f.clean, "", None)
293 def test_charfield_cleans_empty_string_when_blank_true(self):
294 f = models.CharField(blank=True)
295 self.assertEqual('', f.clean('', None))
297 def test_integerfield_cleans_valid_string(self):
298 f = models.IntegerField()
299 self.assertEqual(2, f.clean('2', None))
301 def test_integerfield_raises_error_on_invalid_intput(self):
302 f = models.IntegerField()
303 self.assertRaises(ValidationError, f.clean, "a", None)
305 def test_charfield_with_choices_cleans_valid_choice(self):
306 f = models.CharField(max_length=1, choices=[('a','A'), ('b','B')])
307 self.assertEqual('a', f.clean('a', None))
309 def test_charfield_with_choices_raises_error_on_invalid_choice(self):
310 f = models.CharField(choices=[('a','A'), ('b','B')])
311 self.assertRaises(ValidationError, f.clean, "not a", None)
313 def test_choices_validation_supports_named_groups(self):
314 f = models.IntegerField(choices=(('group',((10,'A'),(20,'B'))),(30,'C')))
315 self.assertEqual(10, f.clean(10, None))
317 def test_nullable_integerfield_raises_error_with_blank_false(self):
318 f = models.IntegerField(null=True, blank=False)
319 self.assertRaises(ValidationError, f.clean, None, None)
321 def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self):
322 f = models.IntegerField(null=True, blank=True)
323 self.assertEqual(None, f.clean(None, None))
325 def test_integerfield_raises_error_on_empty_input(self):
326 f = models.IntegerField(null=False)
327 self.assertRaises(ValidationError, f.clean, None, None)
328 self.assertRaises(ValidationError, f.clean, '', None)
330 def test_integerfield_validates_zero_against_choices(self):
331 f = models.IntegerField(choices=((1, 1),))
332 self.assertRaises(ValidationError, f.clean, '0', None)
334 def test_charfield_raises_error_on_empty_input(self):
335 f = models.CharField(null=False)
336 self.assertRaises(ValidationError, f.clean, None, None)
338 def test_datefield_cleans_date(self):
339 f = models.DateField()
340 self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', None))
342 def test_boolean_field_doesnt_accept_empty_input(self):
343 f = models.BooleanField()
344 self.assertRaises(ValidationError, f.clean, None, None)
347 class BigIntegerFieldTests(test.TestCase):
348 def test_limits(self):
349 # Ensure that values that are right at the limits can be saved
350 # and then retrieved without corruption.
351 maxval = 9223372036854775807
352 minval = -maxval - 1
353 BigInt.objects.create(value=maxval)
354 qs = BigInt.objects.filter(value__gte=maxval)
355 self.assertEqual(qs.count(), 1)
356 self.assertEqual(qs[0].value, maxval)
357 BigInt.objects.create(value=minval)
358 qs = BigInt.objects.filter(value__lte=minval)
359 self.assertEqual(qs.count(), 1)
360 self.assertEqual(qs[0].value, minval)
362 def test_types(self):
363 b = BigInt(value = 0)
364 self.assertTrue(isinstance(b.value, six.integer_types))
365 b.save()
366 self.assertTrue(isinstance(b.value, six.integer_types))
367 b = BigInt.objects.all()[0]
368 self.assertTrue(isinstance(b.value, six.integer_types))
370 def test_coercing(self):
371 BigInt.objects.create(value ='10')
372 b = BigInt.objects.get(value = '10')
373 self.assertEqual(b.value, 10)
375 class TypeCoercionTests(test.TestCase):
377 Test that database lookups can accept the wrong types and convert
378 them with no error: especially on Postgres 8.3+ which does not do
379 automatic casting at the DB level. See #10015.
382 def test_lookup_integer_in_charfield(self):
383 self.assertEqual(Post.objects.filter(title=9).count(), 0)
385 def test_lookup_integer_in_textfield(self):
386 self.assertEqual(Post.objects.filter(body=24).count(), 0)
388 class FileFieldTests(unittest.TestCase):
389 def test_clearable(self):
391 Test that FileField.save_form_data will clear its instance attribute
392 value if passed False.
395 d = Document(myfile='something.txt')
396 self.assertEqual(d.myfile, 'something.txt')
397 field = d._meta.get_field('myfile')
398 field.save_form_data(d, False)
399 self.assertEqual(d.myfile, '')
401 def test_unchanged(self):
403 Test that FileField.save_form_data considers None to mean "no change"
404 rather than "clear".
407 d = Document(myfile='something.txt')
408 self.assertEqual(d.myfile, 'something.txt')
409 field = d._meta.get_field('myfile')
410 field.save_form_data(d, None)
411 self.assertEqual(d.myfile, 'something.txt')
413 def test_changed(self):
415 Test that FileField.save_form_data, if passed a truthy value, updates
416 its instance attribute.
419 d = Document(myfile='something.txt')
420 self.assertEqual(d.myfile, 'something.txt')
421 field = d._meta.get_field('myfile')
422 field.save_form_data(d, 'else.txt')
423 self.assertEqual(d.myfile, 'else.txt')
426 class PrepValueTest(test.TestCase):
427 def test_AutoField(self):
428 self.assertIsInstance(AutoField(primary_key=True).get_prep_value(1), int)
430 @unittest.skipIf(six.PY3, "Python 3 has no `long` type.")
431 def test_BigIntegerField(self):
432 self.assertIsInstance(BigIntegerField().get_prep_value(long(9999999999999999999)), long)
434 def test_BooleanField(self):
435 self.assertIsInstance(BooleanField().get_prep_value(True), bool)
437 def test_CharField(self):
438 self.assertIsInstance(CharField().get_prep_value(''), six.text_type)
439 self.assertIsInstance(CharField().get_prep_value(0), six.text_type)
441 def test_CommaSeparatedIntegerField(self):
442 self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value('1,2'), six.text_type)
443 self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value(0), six.text_type)
445 def test_DateField(self):
446 self.assertIsInstance(DateField().get_prep_value(datetime.date.today()), datetime.date)
448 def test_DateTimeField(self):
449 self.assertIsInstance(DateTimeField().get_prep_value(datetime.datetime.now()), datetime.datetime)
451 def test_DecimalField(self):
452 self.assertIsInstance(DecimalField().get_prep_value(Decimal('1.2')), Decimal)
454 def test_EmailField(self):
455 self.assertIsInstance(EmailField().get_prep_value('mailbox@domain.com'), six.text_type)
457 def test_FileField(self):
458 self.assertIsInstance(FileField().get_prep_value('filename.ext'), six.text_type)
459 self.assertIsInstance(FileField().get_prep_value(0), six.text_type)
461 def test_FilePathField(self):
462 self.assertIsInstance(FilePathField().get_prep_value('tests.py'), six.text_type)
463 self.assertIsInstance(FilePathField().get_prep_value(0), six.text_type)
465 def test_FloatField(self):
466 self.assertIsInstance(FloatField().get_prep_value(1.2), float)
468 def test_ImageField(self):
469 self.assertIsInstance(ImageField().get_prep_value('filename.ext'), six.text_type)
471 def test_IntegerField(self):
472 self.assertIsInstance(IntegerField().get_prep_value(1), int)
474 def test_IPAddressField(self):
475 self.assertIsInstance(IPAddressField().get_prep_value('127.0.0.1'), six.text_type)
476 self.assertIsInstance(IPAddressField().get_prep_value(0), six.text_type)
478 def test_GenericIPAddressField(self):
479 self.assertIsInstance(GenericIPAddressField().get_prep_value('127.0.0.1'), six.text_type)
480 self.assertIsInstance(GenericIPAddressField().get_prep_value(0), six.text_type)
482 def test_NullBooleanField(self):
483 self.assertIsInstance(NullBooleanField().get_prep_value(True), bool)
485 def test_PositiveIntegerField(self):
486 self.assertIsInstance(PositiveIntegerField().get_prep_value(1), int)
488 def test_PositiveSmallIntegerField(self):
489 self.assertIsInstance(PositiveSmallIntegerField().get_prep_value(1), int)
491 def test_SlugField(self):
492 self.assertIsInstance(SlugField().get_prep_value('slug'), six.text_type)
493 self.assertIsInstance(SlugField().get_prep_value(0), six.text_type)
495 def test_SmallIntegerField(self):
496 self.assertIsInstance(SmallIntegerField().get_prep_value(1), int)
498 def test_TextField(self):
499 self.assertIsInstance(TextField().get_prep_value('Abc'), six.text_type)
500 self.assertIsInstance(TextField().get_prep_value(0), six.text_type)
502 def test_TimeField(self):
503 self.assertIsInstance(
504 TimeField().get_prep_value(datetime.datetime.now().time()),
505 datetime.time)
507 def test_URLField(self):
508 self.assertIsInstance(URLField().get_prep_value('http://domain.com'), six.text_type)