#24561 closed New feature (fixed)
Allow model field choices to accept callables.
Reported by: | Christopher Grebs | Owned by: | Natalia Bidart |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Ülgen Sarıkavak | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Django 1.8 introduced the ability to pass a callable for 'choices' but it seems the check-framework was not adapted to this.
Pull Request: https://github.com/django/django/pull/4434/
Change History (13)
comment:1 by , 10 years ago
Component: | Core (System checks) → Database layer (models, ORM) |
---|---|
Patch needs improvement: | set |
Summary: | Allow 'choices'-check to work for callables. → Allow model field choices to accept callables. |
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → New feature |
Version: | 1.8 → master |
comment:2 by , 10 years ago
Oh, then I misread the feature. I'll try to update the patch to port this to the model field choices
as well.
comment:3 by , 8 years ago
Has patch: | unset |
---|---|
Patch needs improvement: | unset |
See also discussion in #28033.
comment:4 by , 7 years ago
Cc: | added |
---|
comment:5 by , 16 months ago
While reviewing/working on #31262, we noticed that the choices refactoring that is being proposed in 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
). Thanks Mariusz for the idea.
-
django/db/migrations/serializer.py
diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 06657ebaab..2c57a21b7c 100644
a b from django.conf import SettingsReference 15 15 from django.db import models 16 16 from django.db.migrations.operations.base import Operation 17 17 from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject 18 from django.utils.choices import CallableChoiceIterator 18 19 from django.utils.functional import LazyObject, Promise 19 20 from django.utils.version import PY311, get_docs_version 20 21 … … class UUIDSerializer(BaseSerializer): 329 330 return "uuid.%s" % repr(self.value), {"import uuid"} 330 331 331 332 333 class CallableChoiceIteratorSerializer(BaseSerializer): 334 335 def serialize(self): 336 return FunctionTypeSerializer(self.value.choices_func).serialize() 337 338 332 339 class Serializer: 333 340 _registry = { 334 341 # Some of these are order-dependent. … … class Serializer: 351 358 types.BuiltinFunctionType, 352 359 types.MethodType, 353 360 ): FunctionTypeSerializer, 361 CallableChoiceIterator: CallableChoiceIteratorSerializer, 354 362 collections.abc.Iterable: IterableSerializer, 355 363 (COMPILED_REGEX_TYPE, RegexObject): RegexSerializer, 356 364 uuid.UUID: UUIDSerializer, -
django/db/models/fields/__init__.py
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 7e56bddffe..6600031cf6 100644
a b class Field(RegisterLookupMixin): 315 315 if not self.choices: 316 316 return [] 317 317 318 if not is_iterable(self.choices) or isinstance( 319 self.choices, (str, CallableChoiceIterator) 320 ): 318 if not is_iterable(self.choices) or isinstance(self.choices, str): 321 319 return [ 322 320 checks.Error( 323 321 "'choices' must be a mapping (e.g. a dictionary) or an iterable "
comment:6 by , 16 months ago
Cc: | removed |
---|
comment:7 by , 16 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:9 by , 16 months ago
Needs documentation: | set |
---|---|
Patch needs improvement: | set |
Setting as patch needs improvement because I'd like to cover a few use cases with the community first.
comment:10 by , 16 months ago
Cc: | added |
---|
comment:13 by , 15 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
It was added for
django.forms.ChoiceField
, but not model fieldchoices
. It might be a reasonable feature request, but it needs to be implemented. It might cause some difficulty in migrations, but I will accept the ticket if someone wants to investigate the possibility.