mirror of https://github.com/django/django.git
Fixed #31124 -- Fixed setting of get_FOO_display() when overriding inherited choices.
Regression in 2d38eb0ab9
This commit is contained in:
parent
d202846ced
commit
29c126bb34
|
@ -764,7 +764,11 @@ class Field(RegisterLookupMixin):
|
|||
if not getattr(cls, self.attname, None):
|
||||
setattr(cls, self.attname, self.descriptor_class(self))
|
||||
if self.choices is not None:
|
||||
if not hasattr(cls, 'get_%s_display' % self.name):
|
||||
# Don't override a get_FOO_display() method defined explicitly on
|
||||
# this class, but don't check methods derived from inheritance, to
|
||||
# allow overriding inherited choices. For more complex inheritance
|
||||
# structures users should override contribute_to_class().
|
||||
if 'get_%s_display' % self.name not in cls.__dict__:
|
||||
setattr(
|
||||
cls,
|
||||
'get_%s_display' % self.name,
|
||||
|
|
|
@ -834,6 +834,15 @@ Note that in the case of identical date values, these methods will use the
|
|||
primary key as a tie-breaker. This guarantees that no records are skipped or
|
||||
duplicated. That also means you cannot use those methods on unsaved objects.
|
||||
|
||||
.. admonition:: Overriding extra instance methods
|
||||
|
||||
In most cases overriding or inheriting ``get_FOO_display()``,
|
||||
``get_next_by_FOO()``, and ``get_previous_by_FOO()` should work as
|
||||
expected. Since they are added by the metaclass however, it is not
|
||||
practical to account for all possible inheritance structures. In more
|
||||
complex cases you should override ``Field.contribute_to_class()`` to set
|
||||
the methods you need.
|
||||
|
||||
Other attributes
|
||||
================
|
||||
|
||||
|
|
|
@ -31,3 +31,7 @@ Bugfixes
|
|||
:class:`~django.contrib.postgres.aggregates.ArrayAgg` and
|
||||
:class:`~django.contrib.postgres.aggregates.StringAgg` with ``filter``
|
||||
argument when used in a ``Subquery`` (:ticket:`31097`).
|
||||
|
||||
* Fixed a regression in Django 2.2.7 that caused
|
||||
:meth:`~django.db.models.Model.get_FOO_display` to work incorrectly when
|
||||
overriding inherited choices (:ticket:`31124`).
|
||||
|
|
|
@ -178,6 +178,19 @@ class GetFieldDisplayTests(SimpleTestCase):
|
|||
f = FooBar(foo_bar=1)
|
||||
self.assertEqual(f.get_foo_bar_display(), 'something')
|
||||
|
||||
def test_overriding_inherited_FIELD_display(self):
|
||||
class Base(models.Model):
|
||||
foo = models.CharField(max_length=254, choices=[('A', 'Base A')])
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class Child(Base):
|
||||
foo = models.CharField(max_length=254, choices=[('A', 'Child A'), ('B', 'Child B')])
|
||||
|
||||
self.assertEqual(Child(foo='A').get_foo_display(), 'Child A')
|
||||
self.assertEqual(Child(foo='B').get_foo_display(), 'Child B')
|
||||
|
||||
def test_iterator_choices(self):
|
||||
"""
|
||||
get_choices() works with Iterators.
|
||||
|
|
Loading…
Reference in New Issue