#24561: Allow model field choices to accept callables.
-------------------------------------+-------------------------------------
Reporter: Christopher Grebs | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Natalia Bidart):
While reviewing/working on #31262, we noticed that the choices refactoring
that is being proposed in [https://github.com/django/django/pull/16943 PR
#16943] will help considerably to this ticket. Besides what is discussed
in that PR, the following diff should allow model field's callable
`choices` to be serialized as functions (similar to callable `default` or
form ChoiceField's `choices`).
{{{
#!diff
diff --git a/django/db/migrations/serializer.py
b/django/db/migrations/serializer.py
index 06657ebaab..2c57a21b7c 100644
--- a/django/db/migrations/serializer.py
+++ b/django/db/migrations/serializer.py
@@ -15,6 +15,7 @@ from django.conf import SettingsReference
from django.db import models
from django.db.migrations.operations.base import Operation
from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
+from django.utils.choices import CallableChoiceIterator
from django.utils.functional import LazyObject, Promise
from django.utils.version import PY311, get_docs_version
@@ -329,6 +330,12 @@ class UUIDSerializer(BaseSerializer):
return "uuid.%s" % repr(self.value), {"import uuid"}
+class CallableChoiceIteratorSerializer(BaseSerializer):
+
+ def serialize(self):
+ return
FunctionTypeSerializer(self.value.choices_func).serialize()
+
+
class Serializer:
_registry = {
# Some of these are order-dependent.
@@ -351,6 +358,7 @@ class Serializer:
types.BuiltinFunctionType,
types.MethodType,
): FunctionTypeSerializer,
+ CallableChoiceIterator: CallableChoiceIteratorSerializer,
collections.abc.Iterable: IterableSerializer,
(COMPILED_REGEX_TYPE, RegexObject): RegexSerializer,
uuid.UUID: UUIDSerializer,
diff --git a/django/db/models/fields/__init__.py
b/django/db/models/fields/__init__.py
index 7e56bddffe..6600031cf6 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -315,9 +315,7 @@ class Field(RegisterLookupMixin):
if not self.choices:
return []
- if not is_iterable(self.choices) or isinstance(
- self.choices, (str, CallableChoiceIterator)
- ):
+ if not is_iterable(self.choices) or isinstance(self.choices,
str):
return [
checks.Error(
"'choices' must be a mapping (e.g. a dictionary) or
an iterable "
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24561#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018a2916eb66-e462b05c-fc18-457c-a922-a7db08b50b3f-000000%40eu-central-1.amazonses.com.