Opened 3 weeks ago

Closed 3 weeks ago

#36548 closed Bug (invalid)

GeneratedField ignores it's output field "choices" argument

Reported by: Olivier Dalang Owned by:
Component: Database layer (models, ORM) Version: 5.2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hello !

GeneratedFields take the "output_field" argument to define the field's data type. One can set a CharField with the "choices" argument as output type.

Unfortunately, the resulting field doesn't behave as a regular CharField with the choices argument (it seems the "choices" is just ignored).

I don't know all internal implications around GeneratedField and output_type, but naively I would expect this to work, just as I expect GeneratedFields of type DateField to output actual python dates. This not working makes it difficult to transition from/to GeneratedFields in migration scenarios, prevents nice integration in django admin (such as labels for filters), and generally requires boilerplate code to map back to the display value.

Below is a small example to reproduce the issue.

Cheers !!

Olivier

class YearInSchool(models.TextChoices):
    FRESHMAN = "FR", "Freshman"
    SOPHOMORE = "SO", "Sophomore"

class MyModel(models.Model):
    normal_choice = models.CharField(
        choices=YearInSchool, default=YearInSchool.FRESHMAN
    )
    generated_choice = models.GeneratedField(
        expression=models.F("normal_choice"),
        output_field=models.CharField(choices=YearInSchool),
        db_persist=False,
    )
myobj = MyModel.objects.create() 

myobj.get_normal_choice_display()  # works as expected
# 'Freshman'

myobj.get_generated_choice_display()  # oh no, non of these choices goodies :-(
# AttributeError: 'MyModel' object has no attribute 'get_generated_choice_display'.

myobj.normal_choice  # works as expected
# YearInSchool.FRESHMAN

myobj.generated_choice  # we get the raw string
# 'FR'

Change History (1)

comment:1 by Sarah Boyce, 3 weeks ago

Component: UncategorizedDatabase layer (models, ORM)
Resolution: invalid
Status: newclosed
Type: UncategorizedBug

Similar to #35566, choices needs to be set on GeneratedField so

    generated_choice = models.GeneratedField(
        expression=models.F("normal_choice"),
        output_field=models.CharField(choices=YearInSchool),
        db_persist=False,
        choices=YearInSchool,
    )

In which case:

myobj = MyModel.objects.create() 
myobj.get_normal_choice_display()
# 'Freshman'
myobj.get_generated_choice_display()
# 'Freshman'
myobj.normal_choice  # driven by the default value which wouldn't make sense for the GeneratedField
# YearInSchool.FRESHMAN
myobj.generated_choice
# 'FR'

myobj.refresh_from_db()
myobj.normal_choice
# 'FR'
myobj.generated_choice
# 'FR'
Note: See TracTickets for help on using tickets.
Back to Top