--
Ticket URL: <https://code.djangoproject.com/ticket/31124>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => needsinfo
* component: Uncategorized => Database layer (models, ORM)
* easy: 1 => 0
Comment:
Thanks for this report. Can you provide models and describe expected
behavior? Can you also check if it's not a duplicate of #30931?, that was
fixed in Django 2.2.7.
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:1>
Old description:
> Given a base model with choices A containing 3 tuples
> Child Model inherits the base model overrides the choices A and adds 2
> more tuples
> get_foo_display does not work correctly for the new tuples added
New description:
Given a base model with choices A containing 3 tuples
Child Model inherits the base model overrides the choices A and adds 2
more tuples
get_foo_display does not work correctly for the new tuples added
Example:
{{{
class A(models.Model):
foo_choice = Choices(("A","output1"),("B","output2"))
field_foo = models.CharField(max_length=254,choices=foo_choice)
class Meta:
abstract:True
class B(A):
foo_choice = Choices(("A","output1"),("B","output2"),("C","output3"))
field_foo = models.CharField(max_length=254,choices=foo_choice)
}}}
Upon invoking get_field_foo_display() on instance of B ,
For value "A" and "B" the output works correctly i.e. returns "output1" /
"output2"
but for value "C" the method returns "C" and not "output3" which is the
expected behaviour
--
Comment (by Yash Jhunjhunwala):
Replying to [comment:1 felixxm]:
> Thanks for this report. Can you provide models and describe expected
behavior? Can you also check if it's not a duplicate of #30931?, that was
fixed in Django 2.2.7.
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:2>
Comment (by Yash Jhunjhunwala):
Added the models and expected behaviour. It is not a duplicate of #30931.
Using Django 2.2.9
> Replying to [comment:1 felixxm]:
> > Thanks for this report. Can you provide models and describe expected
behavior? Can you also check if it's not a duplicate of #30931?, that was
fixed in Django 2.2.7.
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:3>
* status: closed => new
* cc: Carlton Gibson, Sergey Fedoseev (added)
* version: 2.2 => 3.0
* resolution: needsinfo =>
* stage: Unreviewed => Accepted
Old description:
> Given a base model with choices A containing 3 tuples
> Child Model inherits the base model overrides the choices A and adds 2
> more tuples
> get_foo_display does not work correctly for the new tuples added
>
> Example:
>
> {{{
> class A(models.Model):
> foo_choice = Choices(("A","output1"),("B","output2"))
> field_foo = models.CharField(max_length=254,choices=foo_choice)
> class Meta:
> abstract:True
>
> class B(A):
> foo_choice = Choices(("A","output1"),("B","output2"),("C","output3"))
> field_foo = models.CharField(max_length=254,choices=foo_choice)
> }}}
>
> Upon invoking get_field_foo_display() on instance of B ,
> For value "A" and "B" the output works correctly i.e. returns "output1" /
> "output2"
> but for value "C" the method returns "C" and not "output3" which is the
> expected behaviour
New description:
Given a base model with choices A containing 3 tuples
Child Model inherits the base model overrides the choices A and adds 2
more tuples
get_foo_display does not work correctly for the new tuples added
Example:
{{{
class A(models.Model):
foo_choice = [("A","output1"),("B","output2")]
field_foo = models.CharField(max_length=254,choices=foo_choice)
class Meta:
abstract = True
class B(A):
foo_choice = [("A","output1"),("B","output2"),("C","output3")]
field_foo = models.CharField(max_length=254,choices=foo_choice)
}}}
Upon invoking get_field_foo_display() on instance of B ,
For value "A" and "B" the output works correctly i.e. returns "output1" /
"output2"
but for value "C" the method returns "C" and not "output3" which is the
expected behaviour
--
Comment:
Thanks for an extra info. I was able to reproduce this issue, e.g.
{{{
>>> B.objects.create(field_foo='A').get_field_foo_display()
output1
>>> B.objects.create(field_foo='B').get_field_foo_display()
output2
>>> B.objects.create(field_foo='C').get_field_foo_display()
C
}}}
Regression in 2d38eb0ab9f78d68c083a5b78b1eca39027b279a.
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:4>
* owner: nobody => woopsix
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:5>
Comment (by George Popides):
After digging in, i have found that the choices of B model are the same
with the A model, despiite them being the proper ones in __init__.
Migration is correct, so now i must find why the choices of model B are
ignored.
Being my first issue, some hints would be appreciated.
Thanks
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:6>
Comment (by George Popides):
https://github.com/django/django/pull/12266
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:7>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:8>
Comment (by zeynel):
Replying to [comment:10 George Popides]:
> Why would checking on fields class be a bad idea?
> If you are a field of a model that is not abstract but your parent is an
abstract method, wouldn't you want to override your parent's method if you
both have the same method?
Well it is not something I would prefer because it makes two classes
tightly coupled to each other, which means it is hard to change one
without touching to the other one and you always need to think about side
effects of your change. Which eventually makes this two classes hard to
test and makes the codebase hard to maintain.
Your logic about overriding might/or might not be true. I would just
execute this logic on `ModelBase` rather than `Field`.
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:11>
Comment (by Carlton Gibson):
I've opened https://github.com/django/django/pull/12284 which provides a
fix for this, but also demonstrates how this issue will keep coming up...
My inclination here is to back-out the fix for #30931 and document
overriding `_get_FIELD_display()` for this kind of use-case.
My worry is that we get ever more baroque in handling the edge-cases... —
but we could take the fix here and draw a line at that point maybe?
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:12>
* needs_better_patch: 1 => 0
* severity: Normal => Release blocker
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:13>
* owner: George Popides => Carlton Gibson
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:14>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:15>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"29c126bb349526b5f1cd78facbe9f25906f18563" 29c126bb]:
{{{
#!CommitTicketReference repository=""
revision="29c126bb349526b5f1cd78facbe9f25906f18563"
Fixed #31124 -- Fixed setting of get_FOO_display() when overriding
inherited choices.
Regression in 2d38eb0ab9f78d68c083a5b78b1eca39027b279a
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:16>
Comment (by Carlton Gibson <carlton.gibson@…>):
In [changeset:"57468eaff3de78918be5fb15a7984e49d7d3d103" 57468ea]:
{{{
#!CommitTicketReference repository=""
revision="57468eaff3de78918be5fb15a7984e49d7d3d103"
[3.0.x] Fixed #31124 -- Fixed setting of get_FOO_display() when overriding
inherited choices.
Regression in 2d38eb0ab9f78d68c083a5b78b1eca39027b279a
Backport of 29c126bb349526b5f1cd78facbe9f25906f18563 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31124#comment:17>