Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #32132 -- Fixed column types in m2m intermediary tables for Positive(Big/Small)IntegerFields. #13592

Merged
merged 2 commits into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 21 additions & 10 deletions django/db/models/fields/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,13 @@ def formfield(self, **kwargs):
})


class SmallIntegerField(IntegerField):
description = _('Small integer')

def get_internal_type(self):
return 'SmallIntegerField'


class IPAddressField(Field):
empty_strings_allowed = False
description = _("IPv4 address")
Expand Down Expand Up @@ -2006,6 +2013,17 @@ def get_internal_type(self):


class PositiveIntegerRelDbTypeMixin:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
if not hasattr(cls, 'integer_field_class'):
cls.integer_field_class = next(
(
parent
for parent in cls.__mro__[1:]
if issubclass(parent, IntegerField)
),
None,
)

def rel_db_type(self, connection):
"""
Expand All @@ -2019,10 +2037,10 @@ def rel_db_type(self, connection):
if connection.features.related_fields_match_type:
return self.db_type(connection)
else:
return IntegerField().db_type(connection=connection)
return self.integer_field_class().db_type(connection=connection)
felixxm marked this conversation as resolved.
Show resolved Hide resolved


class PositiveBigIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField):
class PositiveBigIntegerField(PositiveIntegerRelDbTypeMixin, BigIntegerField):
description = _('Positive big integer')

def get_internal_type(self):
Expand All @@ -2048,7 +2066,7 @@ def formfield(self, **kwargs):
})


class PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField):
class PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, SmallIntegerField):
felixxm marked this conversation as resolved.
Show resolved Hide resolved
description = _("Positive small integer")

def get_internal_type(self):
Expand Down Expand Up @@ -2094,13 +2112,6 @@ def formfield(self, **kwargs):
})


class SmallIntegerField(IntegerField):
description = _("Small integer")

def get_internal_type(self):
return "SmallIntegerField"


class TextField(Field):
description = _("Text")

Expand Down
3 changes: 3 additions & 0 deletions tests/model_fields/test_autofield.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@

class AutoFieldTests(IntegerFieldTests):
model = AutoModel
rel_db_type_class = models.IntegerField


class BigAutoFieldTests(BigIntegerFieldTests):
model = BigAutoModel
rel_db_type_class = models.BigIntegerField


class SmallAutoFieldTests(SmallIntegerFieldTests):
model = SmallAutoModel
rel_db_type_class = models.SmallIntegerField


class AutoFieldInheritanceTests(SimpleTestCase):
Expand Down
23 changes: 23 additions & 0 deletions tests/model_fields/test_integerfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
class IntegerFieldTests(TestCase):
model = IntegerModel
documented_range = (-2147483648, 2147483647)
rel_db_type_class = models.IntegerField

@property
def backend_range(self):
Expand Down Expand Up @@ -154,25 +155,42 @@ def test_invalid_value(self):
with self.assertRaisesMessage(exception, msg):
self.model.objects.create(value=value)

def test_rel_db_type(self):
field = self.model._meta.get_field('value')
rel_db_type = field.rel_db_type(connection)
self.assertEqual(rel_db_type, self.rel_db_type_class().db_type(connection))


class SmallIntegerFieldTests(IntegerFieldTests):
model = SmallIntegerModel
documented_range = (-32768, 32767)
rel_db_type_class = models.SmallIntegerField


class BigIntegerFieldTests(IntegerFieldTests):
model = BigIntegerModel
documented_range = (-9223372036854775808, 9223372036854775807)
rel_db_type_class = models.BigIntegerField


class PositiveSmallIntegerFieldTests(IntegerFieldTests):
model = PositiveSmallIntegerModel
documented_range = (0, 32767)
rel_db_type_class = (
models.PositiveSmallIntegerField
if connection.features.related_fields_match_type
else models.SmallIntegerField
)


class PositiveIntegerFieldTests(IntegerFieldTests):
model = PositiveIntegerModel
documented_range = (0, 2147483647)
rel_db_type_class = (
models.PositiveIntegerField
if connection.features.related_fields_match_type
else models.IntegerField
)

@unittest.skipIf(connection.vendor == 'sqlite', "SQLite doesn't have a constraint.")
def test_negative_values(self):
Expand All @@ -185,6 +203,11 @@ def test_negative_values(self):
class PositiveBigIntegerFieldTests(IntegerFieldTests):
model = PositiveBigIntegerModel
documented_range = (0, 9223372036854775807)
rel_db_type_class = (
models.PositiveBigIntegerField
if connection.features.related_fields_match_type
else models.BigIntegerField
)


class ValidationTests(SimpleTestCase):
Expand Down