Fixed #26101 -- Allowed introspection of base_field.model in RangeField

Used the same test and fix as in #25867.
This required initializing base_field in RangeField.__init__,
not when setting the attribute.
This commit is contained in:
anna 2016-04-03 12:39:18 +02:00 committed by Markus Holtermann
parent 319b7112d8
commit b28c60529b
4 changed files with 36 additions and 6 deletions

View File

@ -17,6 +17,24 @@ __all__ = [
class RangeField(models.Field): class RangeField(models.Field):
empty_strings_allowed = False empty_strings_allowed = False
def __init__(self, *args, **kwargs):
# Initializing base_field here ensures that its model matches the model for self.
if hasattr(self, 'base_field'):
self.base_field = self.base_field()
super(RangeField, self).__init__(*args, **kwargs)
@property
def model(self):
try:
return self.__dict__['model']
except KeyError:
raise AttributeError("'%s' object has no attribute 'model'" % self.__class__.__name__)
@model.setter
def model(self, model):
self.__dict__['model'] = model
self.base_field.model = model
def get_prep_value(self, value): def get_prep_value(self, value):
if value is None: if value is None:
return None return None
@ -65,7 +83,7 @@ class RangeField(models.Field):
class IntegerRangeField(RangeField): class IntegerRangeField(RangeField):
base_field = models.IntegerField() base_field = models.IntegerField
range_type = NumericRange range_type = NumericRange
form_field = forms.IntegerRangeField form_field = forms.IntegerRangeField
@ -74,7 +92,7 @@ class IntegerRangeField(RangeField):
class BigIntegerRangeField(RangeField): class BigIntegerRangeField(RangeField):
base_field = models.BigIntegerField() base_field = models.BigIntegerField
range_type = NumericRange range_type = NumericRange
form_field = forms.IntegerRangeField form_field = forms.IntegerRangeField
@ -83,7 +101,7 @@ class BigIntegerRangeField(RangeField):
class FloatRangeField(RangeField): class FloatRangeField(RangeField):
base_field = models.FloatField() base_field = models.FloatField
range_type = NumericRange range_type = NumericRange
form_field = forms.FloatRangeField form_field = forms.FloatRangeField
@ -92,7 +110,7 @@ class FloatRangeField(RangeField):
class DateTimeRangeField(RangeField): class DateTimeRangeField(RangeField):
base_field = models.DateTimeField() base_field = models.DateTimeField
range_type = DateTimeTZRange range_type = DateTimeTZRange
form_field = forms.DateTimeRangeField form_field = forms.DateTimeRangeField
@ -101,7 +119,7 @@ class DateTimeRangeField(RangeField):
class DateRangeField(RangeField): class DateRangeField(RangeField):
base_field = models.DateField() base_field = models.DateField
range_type = DateRange range_type = DateRange
form_field = forms.DateRangeField form_field = forms.DateRangeField

View File

@ -845,7 +845,7 @@ types.
.. attribute:: base_field .. attribute:: base_field
The model field to use. The model field class to use.
.. attribute:: range_type .. attribute:: range_type

View File

@ -705,6 +705,12 @@ Miscellaneous
* :func:`django.views.i18n.set_language` may now return a 204 status code for * :func:`django.views.i18n.set_language` may now return a 204 status code for
AJAX requests. AJAX requests.
* The ``base_field`` attribute of
:class:`~django.contrib.postgres.fields.RangeField` is now a type of field,
not an instance of a field. If you have created a custom subclass of
:class:`~django.contrib.postgres.fields.RangeField`, you should change the
``base_field`` attribute.
.. _deprecated-features-1.10: .. _deprecated-features-1.10:
Features deprecated in 1.10 Features deprecated in 1.10

View File

@ -80,6 +80,12 @@ class TestSaveLoad(PostgreSQLTestCase):
loaded = RangesModel.objects.get() loaded = RangesModel.objects.get()
self.assertIsNone(loaded.ints) self.assertIsNone(loaded.ints)
def test_model_set_on_base_field(self):
instance = RangesModel()
field = instance._meta.get_field('ints')
self.assertEqual(field.model, RangesModel)
self.assertEqual(field.base_field.model, RangesModel)
class TestQuerying(PostgreSQLTestCase): class TestQuerying(PostgreSQLTestCase):