summaryrefslogtreecommitdiff
path: root/django/utils
diff options
context:
space:
mode:
authorNick Pope <nick@nickpope.me.uk>2023-10-16 19:11:18 +0100
committerNatalia <124304+nessita@users.noreply.github.com>2023-10-23 14:54:37 -0300
commitcc5901fa8edc25ce6d67d110c18ddf9f16965e32 (patch)
treed0af62584c37f39f20caf04fab8193c1823a0d25 /django/utils
parentbbe90f3c00eb29a8e86b1b638466029def7f444a (diff)
[5.0.x] Fixed #34899 -- Added blank choice to forms' callable choices lazily.
Backport of 171f91d9ef5177850c2f12b26dd732785f6ac034 from main
Diffstat (limited to 'django/utils')
-rw-r--r--django/utils/choices.py17
1 files changed, 16 insertions, 1 deletions
diff --git a/django/utils/choices.py b/django/utils/choices.py
index 54dbdcb3aa..7f40bce510 100644
--- a/django/utils/choices.py
+++ b/django/utils/choices.py
@@ -1,10 +1,11 @@
from collections.abc import Callable, Iterable, Iterator, Mapping
-from itertools import islice, zip_longest
+from itertools import islice, tee, zip_longest
from django.utils.functional import Promise
__all__ = [
"BaseChoiceIterator",
+ "BlankChoiceIterator",
"CallableChoiceIterator",
"flatten_choices",
"normalize_choices",
@@ -34,6 +35,20 @@ class BaseChoiceIterator:
)
+class BlankChoiceIterator(BaseChoiceIterator):
+ """Iterator to lazily inject a blank choice."""
+
+ def __init__(self, choices, blank_choice):
+ self.choices = choices
+ self.blank_choice = blank_choice
+
+ def __iter__(self):
+ choices, other = tee(self.choices)
+ if not any(value in ("", None) for value, _ in flatten_choices(other)):
+ yield from self.blank_choice
+ yield from choices
+
+
class CallableChoiceIterator(BaseChoiceIterator):
"""Iterator to lazily normalize choices generated by a callable."""