#35566: Support get_FOO_display() on GeneratedField
-------------------------------------+-------------------------------------
Reporter: Ronie Martinez | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Sarah Boyce):
Hello Ronie!
I think that the use of "choices" in a GeneratedField is key here as
there's some specific logic for get_FIELD_display() when choices is set.
For me to be sure, can you share what error you received here (or some
more specifics on how it didn't work if there's no error)?
If you got an error like: `AttributeError: 'Bar' object has no attribute
'get_FOO_display'. Did you mean: 'get_something_else_display'?`
Then I think I understand the issue and have replicated (sample failing
test attached below).
It's also possible you received this error: `AttributeError: Cannot read a
generated field from an unsaved model.` if `get_FOO_display` was called
before the model saved (related to #35560). If this is the issue, can you
share a bit more about when this gets called? Maybe sharing your model's
GeneratedField would also help 🙂
{{{#!diff
diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py
index 652c808b40..3cc856db83 100644
--- a/tests/model_fields/models.py
+++ b/tests/model_fields/models.py
@@ -72,6 +72,18 @@ class WhizIterEmpty(models.Model):
c = models.CharField(choices=iter(()), blank=True, max_length=1)
+class WhizGenerated(models.Model):
+ c = models.IntegerField(choices=Whiz.CHOICES, null=True)
+ c_copy = models.GeneratedField(
+ expression=F("c"),
+ output_field=models.IntegerField(choices=Whiz.CHOICES,
null=True),
+ db_persist=True,
+ )
+
+ class Meta:
+ required_db_features = {"supports_stored_generated_columns"}
+
+
class Choiceful(models.Model):
class Suit(models.IntegerChoices):
DIAMOND = 1, "Diamond"
diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py
index 36e54d4b8b..8d7caf7072 100644
--- a/tests/model_fields/tests.py
+++ b/tests/model_fields/tests.py
@@ -17,6 +17,7 @@ from .models import (
WhizDelayed,
WhizIter,
WhizIterEmpty,
+ WhizGenerated,
)
@@ -297,6 +298,16 @@ class GetFieldDisplayTests(SimpleTestCase):
self.assertEqual(WhizIterEmpty(c="").c, "") # Empty value
+class GetFieldDisplayGeneratedTests(TestCase):
+ def test_choices_and_field_display(self):
+ wg_0 = WhizGenerated.objects.create(c=0)
+ wg_1 = WhizGenerated.objects.create(c=1)
+ wg_none = WhizGenerated.objects.create(c=None)
+ self.assertEqual(wg_0.get_c_copy_display(), "Other")
+ self.assertEqual(wg_1.get_c_copy_display(), "First")
+ self.assertIsNone(wg_none.get_c_display())
+
+
class GetChoicesTests(SimpleTestCase):
def test_empty_choices(self):
choices = []
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/35566#comment:1>