31 lines
1.7 KiB
Diff
31 lines
1.7 KiB
Diff
Based on the issue description and my understanding of Django's architecture, the problem is clear:
|
|
|
|
1. When you create a model instance with an enum value like `MyChoice.FIRST_CHOICE`, Django stores the enum member directly in the instance's `__dict__`
|
|
2. When retrieved from the database, the raw string/int value is returned
|
|
3. This causes inconsistency where `str(my_object.my_str_value)` returns `'MyChoice.FIRST_CHOICE'` for created objects but `'first'` for retrieved objects
|
|
|
|
The fix needs to ensure that when a value is assigned to a field, if it's an enum member, the actual value is extracted. The proper place for this fix is in the `__set__` method of the field descriptor.
|
|
|
|
Looking at the Django codebase structure, the fix should be in `django/db/models/fields/__init__.py` where the `DeferredAttribute` class (or similar descriptor) handles value assignment.
|
|
|
|
Here's the patch:
|
|
|
|
--- a/django/db/models/fields/__init__.py
|
|
+++ b/django/db/models/fields/__init__.py
|
|
@@ -16,6 +16,7 @@ from django.core import checks, exceptions, validators
|
|
from django.db import connection, connections, router
|
|
from django.db.models.constants import LOOKUP_SEP
|
|
from django.db.models.query_utils import DeferredAttribute, RegisterLookupMixin
|
|
+from django.db.models.enums import Choices
|
|
from django.utils import timezone
|
|
from django.utils.datastructures import DictWrapper
|
|
from django.utils.dateparse import (
|
|
@@ -163,6 +164,8 @@ class Field(RegisterLookupMixin):
|
|
|
|
def __set__(self, instance, value):
|
|
instance.__dict__[self.attname] = value
|
|
+ if isinstance(value, Choices):
|
|
+ instance.__dict__[self.attname] = value.value
|
|
|
|
def __reduce__(self):
|
|
"""
|