summaryrefslogtreecommitdiff
path: root/django/forms/fields.py
diff options
context:
space:
mode:
authorNick Pope <nick@nickpope.me.uk>2023-08-31 02:57:40 +0100
committerGitHub <noreply@github.com>2023-08-30 22:57:40 -0300
commit500e01073adda32d5149624ee9a5cb7aa3d3583f (patch)
treef9416872a811aa39646deaf002414e0a7841b6d1 /django/forms/fields.py
parent68a8996bdfce2d191decd7b1c1a2b9fdea8e4b2f (diff)
Fixed #31262 -- Added support for mappings on model fields and ChoiceField's choices.
Diffstat (limited to 'django/forms/fields.py')
-rw-r--r--django/forms/fields.py32
1 files changed, 8 insertions, 24 deletions
diff --git a/django/forms/fields.py b/django/forms/fields.py
index bd226de543..3a0510ffc9 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -17,7 +17,6 @@ from urllib.parse import urlsplit, urlunsplit
from django.core import validators
from django.core.exceptions import ValidationError
-from django.db.models.enums import ChoicesMeta
from django.forms.boundfield import BoundField
from django.forms.utils import from_current_timezone, to_current_timezone
from django.forms.widgets import (
@@ -42,6 +41,7 @@ from django.forms.widgets import (
URLInput,
)
from django.utils import formats
+from django.utils.choices import normalize_choices
from django.utils.dateparse import parse_datetime, parse_duration
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.duration import duration_string
@@ -861,14 +861,6 @@ class NullBooleanField(BooleanField):
pass
-class CallableChoiceIterator:
- def __init__(self, choices_func):
- self.choices_func = choices_func
-
- def __iter__(self):
- yield from self.choices_func()
-
-
class ChoiceField(Field):
widget = Select
default_error_messages = {
@@ -879,8 +871,6 @@ class ChoiceField(Field):
def __init__(self, *, choices=(), **kwargs):
super().__init__(**kwargs)
- if isinstance(choices, ChoicesMeta):
- choices = choices.choices
self.choices = choices
def __deepcopy__(self, memo):
@@ -888,21 +878,15 @@ class ChoiceField(Field):
result._choices = copy.deepcopy(self._choices, memo)
return result
- def _get_choices(self):
+ @property
+ def choices(self):
return self._choices
- def _set_choices(self, value):
- # Setting choices also sets the choices on the widget.
- # choices can be any iterable, but we call list() on it because
- # it will be consumed more than once.
- if callable(value):
- value = CallableChoiceIterator(value)
- else:
- value = list(value)
-
- self._choices = self.widget.choices = value
-
- choices = property(_get_choices, _set_choices)
+ @choices.setter
+ def choices(self, value):
+ # Setting choices on the field also sets the choices on the widget.
+ # Note that the property setter for the widget will re-normalize.
+ self._choices = self.widget.choices = normalize_choices(value)
def to_python(self, value):
"""Return a string."""