Split model_fields tests into different files.
This commit is contained in:
parent
14e6823d09
commit
3c1b572f18
|
@ -121,7 +121,7 @@ class NullBooleanModel(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class BooleanModel(models.Model):
|
class BooleanModel(models.Model):
|
||||||
bfield = models.BooleanField(default=None)
|
bfield = models.BooleanField()
|
||||||
string = models.CharField(max_length=10, default='abc')
|
string = models.CharField(max_length=10, default='abc')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
from .models import DataModel
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryFieldTests(TestCase):
|
||||||
|
binary_data = b'\x00\x46\xFE'
|
||||||
|
|
||||||
|
def test_set_and_retrieve(self):
|
||||||
|
data_set = (self.binary_data, six.memoryview(self.binary_data))
|
||||||
|
for bdata in data_set:
|
||||||
|
dm = DataModel(data=bdata)
|
||||||
|
dm.save()
|
||||||
|
dm = DataModel.objects.get(pk=dm.pk)
|
||||||
|
self.assertEqual(bytes(dm.data), bytes(bdata))
|
||||||
|
# Resave (=update)
|
||||||
|
dm.save()
|
||||||
|
dm = DataModel.objects.get(pk=dm.pk)
|
||||||
|
self.assertEqual(bytes(dm.data), bytes(bdata))
|
||||||
|
# Test default value
|
||||||
|
self.assertEqual(bytes(dm.short_data), b'\x08')
|
||||||
|
|
||||||
|
def test_max_length(self):
|
||||||
|
dm = DataModel(short_data=self.binary_data * 4)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
dm.full_clean()
|
|
@ -0,0 +1,119 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import IntegrityError, connection, models, transaction
|
||||||
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
|
||||||
|
from .models import BooleanModel, FksToBooleans, NullBooleanModel
|
||||||
|
|
||||||
|
|
||||||
|
class BooleanFieldTests(TestCase):
|
||||||
|
def _test_get_db_prep_lookup(self, f):
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
|
||||||
|
|
||||||
|
def _test_to_python(self, f):
|
||||||
|
self.assertIs(f.to_python(1), True)
|
||||||
|
self.assertIs(f.to_python(0), False)
|
||||||
|
|
||||||
|
def test_booleanfield_get_db_prep_lookup(self):
|
||||||
|
self._test_get_db_prep_lookup(models.BooleanField())
|
||||||
|
|
||||||
|
def test_nullbooleanfield_get_db_prep_lookup(self):
|
||||||
|
self._test_get_db_prep_lookup(models.NullBooleanField())
|
||||||
|
|
||||||
|
def test_booleanfield_to_python(self):
|
||||||
|
self._test_to_python(models.BooleanField())
|
||||||
|
|
||||||
|
def test_nullbooleanfield_to_python(self):
|
||||||
|
self._test_to_python(models.NullBooleanField())
|
||||||
|
|
||||||
|
def test_booleanfield_choices_blank(self):
|
||||||
|
"""
|
||||||
|
BooleanField with choices and defaults doesn't generate a formfield
|
||||||
|
with the blank option (#9640, #10549).
|
||||||
|
"""
|
||||||
|
choices = [(1, 'Si'), (2, 'No')]
|
||||||
|
f = models.BooleanField(choices=choices, default=1, null=False)
|
||||||
|
self.assertEqual(f.formfield().choices, choices)
|
||||||
|
|
||||||
|
def test_return_type(self):
|
||||||
|
b = BooleanModel.objects.create(bfield=True)
|
||||||
|
b.refresh_from_db()
|
||||||
|
self.assertEqual(b.bfield, True)
|
||||||
|
|
||||||
|
b2 = BooleanModel.objects.create(bfield=False)
|
||||||
|
b2.refresh_from_db()
|
||||||
|
self.assertEqual(b2.bfield, False)
|
||||||
|
|
||||||
|
b3 = NullBooleanModel.objects.create(nbfield=True)
|
||||||
|
b3.refresh_from_db()
|
||||||
|
self.assertEqual(b3.nbfield, True)
|
||||||
|
|
||||||
|
b4 = NullBooleanModel.objects.create(nbfield=False)
|
||||||
|
b4.refresh_from_db()
|
||||||
|
self.assertEqual(b4.nbfield, False)
|
||||||
|
|
||||||
|
# When an extra clause exists, the boolean conversions are applied with
|
||||||
|
# an offset (#13293).
|
||||||
|
b5 = BooleanModel.objects.all().extra(select={'string_col': 'string'})[0]
|
||||||
|
self.assertNotIsInstance(b5.pk, bool)
|
||||||
|
|
||||||
|
def test_select_related(self):
|
||||||
|
"""
|
||||||
|
Boolean fields retrieved via select_related() should return booleans.
|
||||||
|
"""
|
||||||
|
bmt = BooleanModel.objects.create(bfield=True)
|
||||||
|
bmf = BooleanModel.objects.create(bfield=False)
|
||||||
|
nbmt = NullBooleanModel.objects.create(nbfield=True)
|
||||||
|
nbmf = NullBooleanModel.objects.create(nbfield=False)
|
||||||
|
m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
|
||||||
|
m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
|
||||||
|
|
||||||
|
# select_related('fk_field_name')
|
||||||
|
ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
|
||||||
|
self.assertEqual(ma.bf.bfield, True)
|
||||||
|
self.assertEqual(ma.nbf.nbfield, True)
|
||||||
|
|
||||||
|
# select_related()
|
||||||
|
mb = FksToBooleans.objects.select_related().get(pk=m1.id)
|
||||||
|
mc = FksToBooleans.objects.select_related().get(pk=m2.id)
|
||||||
|
self.assertEqual(mb.bf.bfield, True)
|
||||||
|
self.assertEqual(mb.nbf.nbfield, True)
|
||||||
|
self.assertEqual(mc.bf.bfield, False)
|
||||||
|
self.assertEqual(mc.nbf.nbfield, False)
|
||||||
|
|
||||||
|
def test_null_default(self):
|
||||||
|
"""
|
||||||
|
A BooleanField defaults to None, which isn't a valid value (#15124).
|
||||||
|
"""
|
||||||
|
boolean_field = BooleanModel._meta.get_field('bfield')
|
||||||
|
self.assertFalse(boolean_field.has_default())
|
||||||
|
b = BooleanModel()
|
||||||
|
self.assertIsNone(b.bfield)
|
||||||
|
with transaction.atomic():
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
b.save()
|
||||||
|
|
||||||
|
nb = NullBooleanModel()
|
||||||
|
self.assertIsNone(nb.nbfield)
|
||||||
|
nb.save() # no error
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationTest(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_boolean_field_doesnt_accept_empty_input(self):
|
||||||
|
f = models.BooleanField()
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean(None, None)
|
||||||
|
|
||||||
|
def test_nullbooleanfield_blank(self):
|
||||||
|
"""
|
||||||
|
NullBooleanField shouldn't throw a validation error when given a value
|
||||||
|
of None.
|
||||||
|
"""
|
||||||
|
nullboolean = NullBooleanModel(nbfield=None)
|
||||||
|
nullboolean.full_clean()
|
|
@ -0,0 +1,59 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import models
|
||||||
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
from django.utils.functional import lazy
|
||||||
|
|
||||||
|
from .models import Post
|
||||||
|
|
||||||
|
|
||||||
|
class TestCharField(TestCase):
|
||||||
|
|
||||||
|
def test_max_length_passed_to_formfield(self):
|
||||||
|
"""
|
||||||
|
CharField passes its max_length attribute to form fields created using
|
||||||
|
the formfield() method.
|
||||||
|
"""
|
||||||
|
cf1 = models.CharField()
|
||||||
|
cf2 = models.CharField(max_length=1234)
|
||||||
|
self.assertIsNone(cf1.formfield().max_length)
|
||||||
|
self.assertEqual(1234, cf2.formfield().max_length)
|
||||||
|
|
||||||
|
def test_lookup_integer_in_charfield(self):
|
||||||
|
self.assertEqual(Post.objects.filter(title=9).count(), 0)
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationTests(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_charfield_raises_error_on_empty_string(self):
|
||||||
|
f = models.CharField()
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean('', None)
|
||||||
|
|
||||||
|
def test_charfield_cleans_empty_string_when_blank_true(self):
|
||||||
|
f = models.CharField(blank=True)
|
||||||
|
self.assertEqual('', f.clean('', None))
|
||||||
|
|
||||||
|
def test_charfield_with_choices_cleans_valid_choice(self):
|
||||||
|
f = models.CharField(max_length=1, choices=[('a', 'A'), ('b', 'B')])
|
||||||
|
self.assertEqual('a', f.clean('a', None))
|
||||||
|
|
||||||
|
def test_charfield_with_choices_raises_error_on_invalid_choice(self):
|
||||||
|
f = models.CharField(choices=[('a', 'A'), ('b', 'B')])
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean('not a', None)
|
||||||
|
|
||||||
|
def test_charfield_get_choices_with_blank_defined(self):
|
||||||
|
f = models.CharField(choices=[('', '<><>'), ('a', 'A')])
|
||||||
|
self.assertEqual(f.get_choices(True), [('', '<><>'), ('a', 'A')])
|
||||||
|
|
||||||
|
def test_charfield_get_choices_doesnt_evaluate_lazy_strings(self):
|
||||||
|
# Regression test for #23098
|
||||||
|
# Will raise ZeroDivisionError if lazy is evaluated
|
||||||
|
lazy_func = lazy(lambda x: 0 / 0, int)
|
||||||
|
f = models.CharField(choices=[(lazy_func('group'), (('a', 'A'), ('b', 'B')))])
|
||||||
|
self.assertEqual(f.get_choices(True)[0], ('', '---------'))
|
||||||
|
|
||||||
|
def test_charfield_raises_error_on_empty_input(self):
|
||||||
|
f = models.CharField(null=False)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean(None, None)
|
|
@ -0,0 +1,22 @@
|
||||||
|
from django.db import connection, models
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class CustomFieldTests(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_get_prep_value_count(self):
|
||||||
|
"""
|
||||||
|
Field values are not prepared twice in get_db_prep_lookup() (#14786).
|
||||||
|
"""
|
||||||
|
class NoopField(models.TextField):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.prep_value_count = 0
|
||||||
|
super(NoopField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_prep_value(self, value):
|
||||||
|
self.prep_value_count += 1
|
||||||
|
return super(NoopField, self).get_prep_value(value)
|
||||||
|
|
||||||
|
field = NoopField()
|
||||||
|
field.get_db_prep_lookup('exact', 'TEST', connection=connection, prepared=False)
|
||||||
|
self.assertEqual(field.prep_value_count, 1)
|
|
@ -0,0 +1,77 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.test import (
|
||||||
|
SimpleTestCase, TestCase, override_settings, skipUnlessDBFeature,
|
||||||
|
)
|
||||||
|
from django.test.utils import requires_tz_support
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from .models import DateTimeModel
|
||||||
|
|
||||||
|
|
||||||
|
class DateTimeFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_datetimefield_to_python_microseconds(self):
|
||||||
|
"""DateTimeField.to_python() supports microseconds."""
|
||||||
|
f = models.DateTimeField()
|
||||||
|
self.assertEqual(f.to_python('2001-01-02 03:04:05.000006'), datetime.datetime(2001, 1, 2, 3, 4, 5, 6))
|
||||||
|
self.assertEqual(f.to_python('2001-01-02 03:04:05.999999'), datetime.datetime(2001, 1, 2, 3, 4, 5, 999999))
|
||||||
|
|
||||||
|
def test_timefield_to_python_microseconds(self):
|
||||||
|
"""TimeField.to_python() supports microseconds."""
|
||||||
|
f = models.TimeField()
|
||||||
|
self.assertEqual(f.to_python('01:02:03.000004'), datetime.time(1, 2, 3, 4))
|
||||||
|
self.assertEqual(f.to_python('01:02:03.999999'), datetime.time(1, 2, 3, 999999))
|
||||||
|
|
||||||
|
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||||
|
def test_datetimes_save_completely(self):
|
||||||
|
dat = datetime.date(2014, 3, 12)
|
||||||
|
datetim = datetime.datetime(2014, 3, 12, 21, 22, 23, 240000)
|
||||||
|
tim = datetime.time(21, 22, 23, 240000)
|
||||||
|
DateTimeModel.objects.create(d=dat, dt=datetim, t=tim)
|
||||||
|
obj = DateTimeModel.objects.first()
|
||||||
|
self.assertTrue(obj)
|
||||||
|
self.assertEqual(obj.d, dat)
|
||||||
|
self.assertEqual(obj.dt, datetim)
|
||||||
|
self.assertEqual(obj.t, tim)
|
||||||
|
|
||||||
|
@override_settings(USE_TZ=False)
|
||||||
|
def test_lookup_date_without_use_tz(self):
|
||||||
|
d = datetime.date(2014, 3, 12)
|
||||||
|
dt1 = datetime.datetime(2014, 3, 12, 21, 22, 23, 240000)
|
||||||
|
dt2 = datetime.datetime(2014, 3, 11, 21, 22, 23, 240000)
|
||||||
|
t = datetime.time(21, 22, 23, 240000)
|
||||||
|
m = DateTimeModel.objects.create(d=d, dt=dt1, t=t)
|
||||||
|
# Other model with different datetime.
|
||||||
|
DateTimeModel.objects.create(d=d, dt=dt2, t=t)
|
||||||
|
self.assertEqual(m, DateTimeModel.objects.get(dt__date=d))
|
||||||
|
|
||||||
|
@requires_tz_support
|
||||||
|
@skipUnlessDBFeature('has_zoneinfo_database')
|
||||||
|
@override_settings(USE_TZ=True, TIME_ZONE='America/Vancouver')
|
||||||
|
def test_lookup_date_with_use_tz(self):
|
||||||
|
d = datetime.date(2014, 3, 12)
|
||||||
|
# The following is equivalent to UTC 2014-03-12 18:34:23.24000.
|
||||||
|
dt1 = datetime.datetime(2014, 3, 12, 10, 22, 23, 240000, tzinfo=timezone.get_current_timezone())
|
||||||
|
# The following is equivalent to UTC 2014-03-13 05:34:23.24000.
|
||||||
|
dt2 = datetime.datetime(2014, 3, 12, 21, 22, 23, 240000, tzinfo=timezone.get_current_timezone())
|
||||||
|
t = datetime.time(21, 22, 23, 240000)
|
||||||
|
m1 = DateTimeModel.objects.create(d=d, dt=dt1, t=t)
|
||||||
|
m2 = DateTimeModel.objects.create(d=d, dt=dt2, t=t)
|
||||||
|
# In Vancouver, we expect both results.
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
DateTimeModel.objects.filter(dt__date=d),
|
||||||
|
[repr(m1), repr(m2)],
|
||||||
|
ordered=False
|
||||||
|
)
|
||||||
|
with self.settings(TIME_ZONE='UTC'):
|
||||||
|
# But in UTC, the __date only matches one of them.
|
||||||
|
self.assertQuerysetEqual(DateTimeModel.objects.filter(dt__date=d), [repr(m1)])
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationTest(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_datefield_cleans_date(self):
|
||||||
|
f = models.DateField()
|
||||||
|
self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', None))
|
|
@ -0,0 +1,74 @@
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from django.core import validators
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import connection, models
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import BigD, Foo
|
||||||
|
|
||||||
|
|
||||||
|
class DecimalFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_to_python(self):
|
||||||
|
f = models.DecimalField(max_digits=4, decimal_places=2)
|
||||||
|
self.assertEqual(f.to_python(3), Decimal('3'))
|
||||||
|
self.assertEqual(f.to_python('3.14'), Decimal('3.14'))
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.to_python('abc')
|
||||||
|
|
||||||
|
def test_default(self):
|
||||||
|
f = models.DecimalField(default=Decimal('0.00'))
|
||||||
|
self.assertEqual(f.get_default(), Decimal('0.00'))
|
||||||
|
|
||||||
|
def test_format(self):
|
||||||
|
f = models.DecimalField(max_digits=5, decimal_places=1)
|
||||||
|
self.assertEqual(f._format(f.to_python(2)), '2.0')
|
||||||
|
self.assertEqual(f._format(f.to_python('2.6')), '2.6')
|
||||||
|
self.assertEqual(f._format(None), None)
|
||||||
|
|
||||||
|
def test_get_db_prep_lookup(self):
|
||||||
|
f = models.DecimalField(max_digits=5, decimal_places=1)
|
||||||
|
self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
|
||||||
|
|
||||||
|
def test_filter_with_strings(self):
|
||||||
|
"""
|
||||||
|
Should be able to filter decimal fields using strings (#8023).
|
||||||
|
"""
|
||||||
|
foo = Foo.objects.create(a='abc', d=Decimal('12.34'))
|
||||||
|
self.assertEqual(list(Foo.objects.filter(d='12.34')), [foo])
|
||||||
|
|
||||||
|
def test_save_without_float_conversion(self):
|
||||||
|
"""
|
||||||
|
Ensure decimals don't go through a corrupting float conversion during
|
||||||
|
save (#5079).
|
||||||
|
"""
|
||||||
|
bd = BigD(d='12.9')
|
||||||
|
bd.save()
|
||||||
|
bd = BigD.objects.get(pk=bd.pk)
|
||||||
|
self.assertEqual(bd.d, Decimal('12.9'))
|
||||||
|
|
||||||
|
def test_lookup_really_big_value(self):
|
||||||
|
"""
|
||||||
|
Really big values can be used in a filter statement.
|
||||||
|
"""
|
||||||
|
# This should not crash.
|
||||||
|
Foo.objects.filter(d__gte=100000000000)
|
||||||
|
|
||||||
|
def test_max_digits_validation(self):
|
||||||
|
field = models.DecimalField(max_digits=2)
|
||||||
|
expected_message = validators.DecimalValidator.messages['max_digits'] % {'max': 2}
|
||||||
|
with self.assertRaisesMessage(ValidationError, expected_message):
|
||||||
|
field.clean(100, None)
|
||||||
|
|
||||||
|
def test_max_decimal_places_validation(self):
|
||||||
|
field = models.DecimalField(decimal_places=1)
|
||||||
|
expected_message = validators.DecimalValidator.messages['max_decimal_places'] % {'max': 1}
|
||||||
|
with self.assertRaisesMessage(ValidationError, expected_message):
|
||||||
|
field.clean(Decimal('0.99'), None)
|
||||||
|
|
||||||
|
def test_max_whole_digits_validation(self):
|
||||||
|
field = models.DecimalField(max_digits=3, decimal_places=1)
|
||||||
|
expected_message = validators.DecimalValidator.messages['max_whole_digits'] % {'max': 2}
|
||||||
|
with self.assertRaisesMessage(ValidationError, expected_message):
|
||||||
|
field.clean(Decimal('999'), None)
|
|
@ -0,0 +1,52 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import Document
|
||||||
|
|
||||||
|
|
||||||
|
class FileFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_clearable(self):
|
||||||
|
"""
|
||||||
|
FileField.save_form_data() will clear its instance attribute value if
|
||||||
|
passed False.
|
||||||
|
"""
|
||||||
|
d = Document(myfile='something.txt')
|
||||||
|
self.assertEqual(d.myfile, 'something.txt')
|
||||||
|
field = d._meta.get_field('myfile')
|
||||||
|
field.save_form_data(d, False)
|
||||||
|
self.assertEqual(d.myfile, '')
|
||||||
|
|
||||||
|
def test_unchanged(self):
|
||||||
|
"""
|
||||||
|
FileField.save_form_data() considers None to mean "no change" rather
|
||||||
|
than "clear".
|
||||||
|
"""
|
||||||
|
d = Document(myfile='something.txt')
|
||||||
|
self.assertEqual(d.myfile, 'something.txt')
|
||||||
|
field = d._meta.get_field('myfile')
|
||||||
|
field.save_form_data(d, None)
|
||||||
|
self.assertEqual(d.myfile, 'something.txt')
|
||||||
|
|
||||||
|
def test_changed(self):
|
||||||
|
"""
|
||||||
|
FileField.save_form_data(), if passed a truthy value, updates its
|
||||||
|
instance attribute.
|
||||||
|
"""
|
||||||
|
d = Document(myfile='something.txt')
|
||||||
|
self.assertEqual(d.myfile, 'something.txt')
|
||||||
|
field = d._meta.get_field('myfile')
|
||||||
|
field.save_form_data(d, 'else.txt')
|
||||||
|
self.assertEqual(d.myfile, 'else.txt')
|
||||||
|
|
||||||
|
def test_delete_when_file_unset(self):
|
||||||
|
"""
|
||||||
|
Calling delete on an unset FileField should not call the file deletion
|
||||||
|
process, but fail silently (#20660).
|
||||||
|
"""
|
||||||
|
d = Document()
|
||||||
|
d.myfile.delete()
|
||||||
|
|
||||||
|
def test_refresh_from_db(self):
|
||||||
|
d = Document.objects.create(myfile='something.txt')
|
||||||
|
d.refresh_from_db()
|
||||||
|
self.assertIs(d.myfile.instance, d)
|
|
@ -0,0 +1,34 @@
|
||||||
|
from django.db import transaction
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import FloatModel
|
||||||
|
|
||||||
|
|
||||||
|
class TestFloatField(TestCase):
|
||||||
|
|
||||||
|
def test_float_validates_object(self):
|
||||||
|
instance = FloatModel(size=2.5)
|
||||||
|
# Try setting float field to unsaved object
|
||||||
|
instance.size = instance
|
||||||
|
with transaction.atomic():
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
instance.save()
|
||||||
|
# Set value to valid and save
|
||||||
|
instance.size = 2.5
|
||||||
|
instance.save()
|
||||||
|
self.assertTrue(instance.id)
|
||||||
|
# Set field to object on saved instance
|
||||||
|
instance.size = instance
|
||||||
|
msg = (
|
||||||
|
'Tried to update field model_fields.FloatModel.size with a model '
|
||||||
|
'instance, <FloatModel: FloatModel object>. Use a value '
|
||||||
|
'compatible with FloatField.'
|
||||||
|
)
|
||||||
|
with transaction.atomic():
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
instance.save()
|
||||||
|
# Try setting field to object on retrieved object
|
||||||
|
obj = FloatModel.objects.get(pk=instance.id)
|
||||||
|
obj.size = obj
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
obj.save()
|
|
@ -0,0 +1,96 @@
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from django.apps import apps
|
||||||
|
from django.core import checks
|
||||||
|
from django.db import models
|
||||||
|
from django.test import TestCase, skipIfDBFeature
|
||||||
|
from django.test.utils import isolate_apps
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
from .models import Bar, FkToChar, Foo, PrimaryKeyCharModel
|
||||||
|
|
||||||
|
|
||||||
|
class ForeignKeyTests(TestCase):
|
||||||
|
|
||||||
|
def test_callable_default(self):
|
||||||
|
"""A lazy callable may be used for ForeignKey.default."""
|
||||||
|
a = Foo.objects.create(id=1, a='abc', d=Decimal('12.34'))
|
||||||
|
b = Bar.objects.create(b='bcd')
|
||||||
|
self.assertEqual(b.a, a)
|
||||||
|
|
||||||
|
@skipIfDBFeature('interprets_empty_strings_as_nulls')
|
||||||
|
def test_empty_string_fk(self):
|
||||||
|
"""
|
||||||
|
Empty strings foreign key values don't get converted to None (#19299).
|
||||||
|
"""
|
||||||
|
char_model_empty = PrimaryKeyCharModel.objects.create(string='')
|
||||||
|
fk_model_empty = FkToChar.objects.create(out=char_model_empty)
|
||||||
|
fk_model_empty = FkToChar.objects.select_related('out').get(id=fk_model_empty.pk)
|
||||||
|
self.assertEqual(fk_model_empty.out, char_model_empty)
|
||||||
|
|
||||||
|
@isolate_apps('model_fields')
|
||||||
|
def test_warning_when_unique_true_on_fk(self):
|
||||||
|
class Foo(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class FKUniqueTrue(models.Model):
|
||||||
|
fk_field = models.ForeignKey(Foo, models.CASCADE, unique=True)
|
||||||
|
|
||||||
|
model = FKUniqueTrue()
|
||||||
|
expected_warnings = [
|
||||||
|
checks.Warning(
|
||||||
|
'Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.',
|
||||||
|
hint='ForeignKey(unique=True) is usually better served by a OneToOneField.',
|
||||||
|
obj=FKUniqueTrue.fk_field.field,
|
||||||
|
id='fields.W342',
|
||||||
|
)
|
||||||
|
]
|
||||||
|
warnings = model.check()
|
||||||
|
self.assertEqual(warnings, expected_warnings)
|
||||||
|
|
||||||
|
def test_related_name_converted_to_text(self):
|
||||||
|
rel_name = Bar._meta.get_field('a').remote_field.related_name
|
||||||
|
self.assertIsInstance(rel_name, six.text_type)
|
||||||
|
|
||||||
|
def test_abstract_model_pending_operations(self):
|
||||||
|
"""
|
||||||
|
Foreign key fields declared on abstract models should not add lazy
|
||||||
|
relations to resolve relationship declared as string (#24215).
|
||||||
|
"""
|
||||||
|
pending_ops_before = list(apps._pending_operations.items())
|
||||||
|
|
||||||
|
class AbstractForeignKeyModel(models.Model):
|
||||||
|
fk = models.ForeignKey('missing.FK', models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
self.assertIs(AbstractForeignKeyModel._meta.apps, apps)
|
||||||
|
self.assertEqual(
|
||||||
|
pending_ops_before,
|
||||||
|
list(apps._pending_operations.items()),
|
||||||
|
'Pending lookup added for a foreign key on an abstract model'
|
||||||
|
)
|
||||||
|
|
||||||
|
@isolate_apps('model_fields', 'model_fields.tests')
|
||||||
|
def test_abstract_model_app_relative_foreign_key(self):
|
||||||
|
class AbstractReferent(models.Model):
|
||||||
|
reference = models.ForeignKey('Refered', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'model_fields'
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
def assert_app_model_resolved(label):
|
||||||
|
class Refered(models.Model):
|
||||||
|
class Meta:
|
||||||
|
app_label = label
|
||||||
|
|
||||||
|
class ConcreteReferent(AbstractReferent):
|
||||||
|
class Meta:
|
||||||
|
app_label = label
|
||||||
|
|
||||||
|
self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Refered)
|
||||||
|
|
||||||
|
assert_app_model_resolved('model_fields')
|
||||||
|
assert_app_model_resolved('tests')
|
|
@ -0,0 +1,35 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import models
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import GenericIPAddress
|
||||||
|
|
||||||
|
|
||||||
|
class GenericIPAddressFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_genericipaddressfield_formfield_protocol(self):
|
||||||
|
"""
|
||||||
|
GenericIPAddressField with a specified protocol does not generate a
|
||||||
|
formfield without a protocol.
|
||||||
|
"""
|
||||||
|
model_field = models.GenericIPAddressField(protocol='IPv4')
|
||||||
|
form_field = model_field.formfield()
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
form_field.clean('::1')
|
||||||
|
model_field = models.GenericIPAddressField(protocol='IPv6')
|
||||||
|
form_field = model_field.formfield()
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
form_field.clean('127.0.0.1')
|
||||||
|
|
||||||
|
def test_null_value(self):
|
||||||
|
"""
|
||||||
|
Null values should be resolved to None.
|
||||||
|
"""
|
||||||
|
GenericIPAddress.objects.create()
|
||||||
|
o = GenericIPAddress.objects.get()
|
||||||
|
self.assertIsNone(o.ip)
|
||||||
|
|
||||||
|
def test_save_load(self):
|
||||||
|
instance = GenericIPAddress.objects.create(ip='::1')
|
||||||
|
loaded = GenericIPAddress.objects.get()
|
||||||
|
self.assertEqual(loaded.ip, instance.ip)
|
|
@ -0,0 +1,161 @@
|
||||||
|
from django.core import validators
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import connection, models
|
||||||
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
from .models import (
|
||||||
|
BigIntegerModel, IntegerModel, PositiveIntegerModel,
|
||||||
|
PositiveSmallIntegerModel, SmallIntegerModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IntegerFieldTests(TestCase):
|
||||||
|
model = IntegerModel
|
||||||
|
documented_range = (-2147483648, 2147483647)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def backend_range(self):
|
||||||
|
field = self.model._meta.get_field('value')
|
||||||
|
internal_type = field.get_internal_type()
|
||||||
|
return connection.ops.integer_field_range(internal_type)
|
||||||
|
|
||||||
|
def test_documented_range(self):
|
||||||
|
"""
|
||||||
|
Values within the documented safe range pass validation, and can be
|
||||||
|
saved and retrieved without corruption.
|
||||||
|
"""
|
||||||
|
min_value, max_value = self.documented_range
|
||||||
|
|
||||||
|
instance = self.model(value=min_value)
|
||||||
|
instance.full_clean()
|
||||||
|
instance.save()
|
||||||
|
qs = self.model.objects.filter(value__lte=min_value)
|
||||||
|
self.assertEqual(qs.count(), 1)
|
||||||
|
self.assertEqual(qs[0].value, min_value)
|
||||||
|
|
||||||
|
instance = self.model(value=max_value)
|
||||||
|
instance.full_clean()
|
||||||
|
instance.save()
|
||||||
|
qs = self.model.objects.filter(value__gte=max_value)
|
||||||
|
self.assertEqual(qs.count(), 1)
|
||||||
|
self.assertEqual(qs[0].value, max_value)
|
||||||
|
|
||||||
|
def test_backend_range_save(self):
|
||||||
|
"""
|
||||||
|
Backend specific ranges can be saved without corruption.
|
||||||
|
"""
|
||||||
|
min_value, max_value = self.backend_range
|
||||||
|
|
||||||
|
if min_value is not None:
|
||||||
|
instance = self.model(value=min_value)
|
||||||
|
instance.full_clean()
|
||||||
|
instance.save()
|
||||||
|
qs = self.model.objects.filter(value__lte=min_value)
|
||||||
|
self.assertEqual(qs.count(), 1)
|
||||||
|
self.assertEqual(qs[0].value, min_value)
|
||||||
|
|
||||||
|
if max_value is not None:
|
||||||
|
instance = self.model(value=max_value)
|
||||||
|
instance.full_clean()
|
||||||
|
instance.save()
|
||||||
|
qs = self.model.objects.filter(value__gte=max_value)
|
||||||
|
self.assertEqual(qs.count(), 1)
|
||||||
|
self.assertEqual(qs[0].value, max_value)
|
||||||
|
|
||||||
|
def test_backend_range_validation(self):
|
||||||
|
"""
|
||||||
|
Backend specific ranges are enforced at the model validation level
|
||||||
|
(#12030).
|
||||||
|
"""
|
||||||
|
min_value, max_value = self.backend_range
|
||||||
|
|
||||||
|
if min_value is not None:
|
||||||
|
instance = self.model(value=min_value - 1)
|
||||||
|
expected_message = validators.MinValueValidator.message % {
|
||||||
|
'limit_value': min_value,
|
||||||
|
}
|
||||||
|
with self.assertRaisesMessage(ValidationError, expected_message):
|
||||||
|
instance.full_clean()
|
||||||
|
instance.value = min_value
|
||||||
|
instance.full_clean()
|
||||||
|
|
||||||
|
if max_value is not None:
|
||||||
|
instance = self.model(value=max_value + 1)
|
||||||
|
expected_message = validators.MaxValueValidator.message % {
|
||||||
|
'limit_value': max_value,
|
||||||
|
}
|
||||||
|
with self.assertRaisesMessage(ValidationError, expected_message):
|
||||||
|
instance.full_clean()
|
||||||
|
instance.value = max_value
|
||||||
|
instance.full_clean()
|
||||||
|
|
||||||
|
def test_types(self):
|
||||||
|
instance = self.model(value=0)
|
||||||
|
self.assertIsInstance(instance.value, six.integer_types)
|
||||||
|
instance.save()
|
||||||
|
self.assertIsInstance(instance.value, six.integer_types)
|
||||||
|
instance = self.model.objects.get()
|
||||||
|
self.assertIsInstance(instance.value, six.integer_types)
|
||||||
|
|
||||||
|
def test_coercing(self):
|
||||||
|
self.model.objects.create(value='10')
|
||||||
|
instance = self.model.objects.get(value='10')
|
||||||
|
self.assertEqual(instance.value, 10)
|
||||||
|
|
||||||
|
|
||||||
|
class SmallIntegerFieldTests(IntegerFieldTests):
|
||||||
|
model = SmallIntegerModel
|
||||||
|
documented_range = (-32768, 32767)
|
||||||
|
|
||||||
|
|
||||||
|
class BigIntegerFieldTests(IntegerFieldTests):
|
||||||
|
model = BigIntegerModel
|
||||||
|
documented_range = (-9223372036854775808, 9223372036854775807)
|
||||||
|
|
||||||
|
|
||||||
|
class PositiveSmallIntegerFieldTests(IntegerFieldTests):
|
||||||
|
model = PositiveSmallIntegerModel
|
||||||
|
documented_range = (0, 32767)
|
||||||
|
|
||||||
|
|
||||||
|
class PositiveIntegerFieldTests(IntegerFieldTests):
|
||||||
|
model = PositiveIntegerModel
|
||||||
|
documented_range = (0, 2147483647)
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationTests(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_integerfield_cleans_valid_string(self):
|
||||||
|
f = models.IntegerField()
|
||||||
|
self.assertEqual(f.clean('2', None), 2)
|
||||||
|
|
||||||
|
def test_integerfield_raises_error_on_invalid_intput(self):
|
||||||
|
f = models.IntegerField()
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean('a', None)
|
||||||
|
|
||||||
|
def test_choices_validation_supports_named_groups(self):
|
||||||
|
f = models.IntegerField(choices=(('group', ((10, 'A'), (20, 'B'))), (30, 'C')))
|
||||||
|
self.assertEqual(10, f.clean(10, None))
|
||||||
|
|
||||||
|
def test_nullable_integerfield_raises_error_with_blank_false(self):
|
||||||
|
f = models.IntegerField(null=True, blank=False)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean(None, None)
|
||||||
|
|
||||||
|
def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self):
|
||||||
|
f = models.IntegerField(null=True, blank=True)
|
||||||
|
self.assertIsNone(f.clean(None, None))
|
||||||
|
|
||||||
|
def test_integerfield_raises_error_on_empty_input(self):
|
||||||
|
f = models.IntegerField(null=False)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean(None, None)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean('', None)
|
||||||
|
|
||||||
|
def test_integerfield_validates_zero_against_choices(self):
|
||||||
|
f = models.IntegerField(choices=((1, 1),))
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
f.clean('0', None)
|
|
@ -0,0 +1,58 @@
|
||||||
|
from django.apps import apps
|
||||||
|
from django.db import models
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
from django.test.utils import isolate_apps
|
||||||
|
|
||||||
|
|
||||||
|
class ManyToManyFieldTests(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_abstract_model_pending_operations(self):
|
||||||
|
"""
|
||||||
|
Many-to-many fields declared on abstract models should not add lazy
|
||||||
|
relations to resolve relationship declared as string (#24215).
|
||||||
|
"""
|
||||||
|
pending_ops_before = list(apps._pending_operations.items())
|
||||||
|
|
||||||
|
class AbstractManyToManyModel(models.Model):
|
||||||
|
fk = models.ForeignKey('missing.FK', models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
self.assertIs(AbstractManyToManyModel._meta.apps, apps)
|
||||||
|
self.assertEqual(
|
||||||
|
pending_ops_before,
|
||||||
|
list(apps._pending_operations.items()),
|
||||||
|
'Pending lookup added for a many-to-many field on an abstract model'
|
||||||
|
)
|
||||||
|
|
||||||
|
@isolate_apps('model_fields', 'model_fields.tests')
|
||||||
|
def test_abstract_model_app_relative_foreign_key(self):
|
||||||
|
class AbstractReferent(models.Model):
|
||||||
|
reference = models.ManyToManyField('Refered', through='Through')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'model_fields'
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
def assert_app_model_resolved(label):
|
||||||
|
class Refered(models.Model):
|
||||||
|
class Meta:
|
||||||
|
app_label = label
|
||||||
|
|
||||||
|
class Through(models.Model):
|
||||||
|
refered = models.ForeignKey('Refered', on_delete=models.CASCADE)
|
||||||
|
referent = models.ForeignKey('ConcreteReferent', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = label
|
||||||
|
|
||||||
|
class ConcreteReferent(AbstractReferent):
|
||||||
|
class Meta:
|
||||||
|
app_label = label
|
||||||
|
|
||||||
|
self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Refered)
|
||||||
|
self.assertEqual(ConcreteReferent.reference.through, Through)
|
||||||
|
|
||||||
|
assert_app_model_resolved('model_fields')
|
||||||
|
assert_app_model_resolved('tests')
|
|
@ -0,0 +1,138 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import unittest
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from django.db.models.fields import (
|
||||||
|
AutoField, BigIntegerField, BinaryField, BooleanField, CharField,
|
||||||
|
CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField,
|
||||||
|
EmailField, FilePathField, FloatField, GenericIPAddressField, IntegerField,
|
||||||
|
IPAddressField, NullBooleanField, PositiveIntegerField,
|
||||||
|
PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField,
|
||||||
|
TimeField, URLField,
|
||||||
|
)
|
||||||
|
from django.db.models.fields.files import FileField, ImageField
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
from django.utils import six
|
||||||
|
from django.utils.functional import lazy
|
||||||
|
|
||||||
|
|
||||||
|
class PromiseTest(SimpleTestCase):
|
||||||
|
|
||||||
|
def test_AutoField(self):
|
||||||
|
lazy_func = lazy(lambda: 1, int)
|
||||||
|
self.assertIsInstance(AutoField(primary_key=True).get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
|
@unittest.skipIf(six.PY3, 'Python 3 has no `long` type.')
|
||||||
|
def test_BigIntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: long(9999999999999999999), long) # NOQA: long undefined on PY3
|
||||||
|
self.assertIsInstance(BigIntegerField().get_prep_value(lazy_func()), long) # NOQA
|
||||||
|
|
||||||
|
def test_BinaryField(self):
|
||||||
|
lazy_func = lazy(lambda: b'', bytes)
|
||||||
|
self.assertIsInstance(BinaryField().get_prep_value(lazy_func()), bytes)
|
||||||
|
|
||||||
|
def test_BooleanField(self):
|
||||||
|
lazy_func = lazy(lambda: True, bool)
|
||||||
|
self.assertIsInstance(BooleanField().get_prep_value(lazy_func()), bool)
|
||||||
|
|
||||||
|
def test_CharField(self):
|
||||||
|
lazy_func = lazy(lambda: '', six.text_type)
|
||||||
|
self.assertIsInstance(CharField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(CharField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_CommaSeparatedIntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: '1,2', six.text_type)
|
||||||
|
self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_DateField(self):
|
||||||
|
lazy_func = lazy(lambda: datetime.date.today(), datetime.date)
|
||||||
|
self.assertIsInstance(DateField().get_prep_value(lazy_func()), datetime.date)
|
||||||
|
|
||||||
|
def test_DateTimeField(self):
|
||||||
|
lazy_func = lazy(lambda: datetime.datetime.now(), datetime.datetime)
|
||||||
|
self.assertIsInstance(DateTimeField().get_prep_value(lazy_func()), datetime.datetime)
|
||||||
|
|
||||||
|
def test_DecimalField(self):
|
||||||
|
lazy_func = lazy(lambda: Decimal('1.2'), Decimal)
|
||||||
|
self.assertIsInstance(DecimalField().get_prep_value(lazy_func()), Decimal)
|
||||||
|
|
||||||
|
def test_EmailField(self):
|
||||||
|
lazy_func = lazy(lambda: 'mailbox@domain.com', six.text_type)
|
||||||
|
self.assertIsInstance(EmailField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_FileField(self):
|
||||||
|
lazy_func = lazy(lambda: 'filename.ext', six.text_type)
|
||||||
|
self.assertIsInstance(FileField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(FileField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_FilePathField(self):
|
||||||
|
lazy_func = lazy(lambda: 'tests.py', six.text_type)
|
||||||
|
self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_FloatField(self):
|
||||||
|
lazy_func = lazy(lambda: 1.2, float)
|
||||||
|
self.assertIsInstance(FloatField().get_prep_value(lazy_func()), float)
|
||||||
|
|
||||||
|
def test_ImageField(self):
|
||||||
|
lazy_func = lazy(lambda: 'filename.ext', six.text_type)
|
||||||
|
self.assertIsInstance(ImageField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_IntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: 1, int)
|
||||||
|
self.assertIsInstance(IntegerField().get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
|
def test_IPAddressField(self):
|
||||||
|
lazy_func = lazy(lambda: '127.0.0.1', six.text_type)
|
||||||
|
self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_GenericIPAddressField(self):
|
||||||
|
lazy_func = lazy(lambda: '127.0.0.1', six.text_type)
|
||||||
|
self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_NullBooleanField(self):
|
||||||
|
lazy_func = lazy(lambda: True, bool)
|
||||||
|
self.assertIsInstance(NullBooleanField().get_prep_value(lazy_func()), bool)
|
||||||
|
|
||||||
|
def test_PositiveIntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: 1, int)
|
||||||
|
self.assertIsInstance(PositiveIntegerField().get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
|
def test_PositiveSmallIntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: 1, int)
|
||||||
|
self.assertIsInstance(PositiveSmallIntegerField().get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
|
def test_SlugField(self):
|
||||||
|
lazy_func = lazy(lambda: 'slug', six.text_type)
|
||||||
|
self.assertIsInstance(SlugField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(SlugField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_SmallIntegerField(self):
|
||||||
|
lazy_func = lazy(lambda: 1, int)
|
||||||
|
self.assertIsInstance(SmallIntegerField().get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
|
def test_TextField(self):
|
||||||
|
lazy_func = lazy(lambda: 'Abc', six.text_type)
|
||||||
|
self.assertIsInstance(TextField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
lazy_func = lazy(lambda: 0, int)
|
||||||
|
self.assertIsInstance(TextField().get_prep_value(lazy_func()), six.text_type)
|
||||||
|
|
||||||
|
def test_TimeField(self):
|
||||||
|
lazy_func = lazy(lambda: datetime.datetime.now().time(), datetime.time)
|
||||||
|
self.assertIsInstance(TimeField().get_prep_value(lazy_func()), datetime.time)
|
||||||
|
|
||||||
|
def test_URLField(self):
|
||||||
|
lazy_func = lazy(lambda: 'http://domain.com', six.text_type)
|
||||||
|
self.assertIsInstance(URLField().get_prep_value(lazy_func()), six.text_type)
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import BigS, UnicodeSlugField
|
||||||
|
|
||||||
|
|
||||||
|
class SlugFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_slugfield_max_length(self):
|
||||||
|
"""
|
||||||
|
SlugField honors max_length.
|
||||||
|
"""
|
||||||
|
bs = BigS.objects.create(s='slug' * 50)
|
||||||
|
bs = BigS.objects.get(pk=bs.pk)
|
||||||
|
self.assertEqual(bs.s, 'slug' * 50)
|
||||||
|
|
||||||
|
def test_slugfield_unicode_max_length(self):
|
||||||
|
"""
|
||||||
|
SlugField with allow_unicode=True honors max_length.
|
||||||
|
"""
|
||||||
|
bs = UnicodeSlugField.objects.create(s='你好你好' * 50)
|
||||||
|
bs = UnicodeSlugField.objects.get(pk=bs.pk)
|
||||||
|
self.assertEqual(bs.s, '你好你好' * 50)
|
|
@ -0,0 +1,25 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import Post
|
||||||
|
|
||||||
|
|
||||||
|
class TextFieldTests(TestCase):
|
||||||
|
|
||||||
|
def test_max_length_passed_to_formfield(self):
|
||||||
|
"""
|
||||||
|
TextField passes its max_length attribute to form fields created using
|
||||||
|
their formfield() method.
|
||||||
|
"""
|
||||||
|
tf1 = models.TextField()
|
||||||
|
tf2 = models.TextField(max_length=2345)
|
||||||
|
self.assertIsNone(tf1.formfield().max_length)
|
||||||
|
self.assertEqual(2345, tf2.formfield().max_length)
|
||||||
|
|
||||||
|
def test_to_python(self):
|
||||||
|
"""TextField.to_python() should return a string."""
|
||||||
|
f = models.TextField()
|
||||||
|
self.assertEqual(f.to_python(1), '1')
|
||||||
|
|
||||||
|
def test_lookup_integer_in_textfield(self):
|
||||||
|
self.assertEqual(Post.objects.filter(body=24).count(), 0)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue