mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed #24483 -- Prevented keepdb from breaking with generator choices.
If Field.choices is provided as an iterator, consume it in __init__ instead of using itertools.tee (which ends up holding everything in memory anyway). Fixes a bug where deconstruct() was consuming the iterator but bypassing the call to `tee`.
This commit is contained in:
committed by
Tim Graham
parent
118cae2df8
commit
80e3444eca
@@ -9,7 +9,6 @@ import math
|
||||
import uuid
|
||||
import warnings
|
||||
from base64 import b64decode, b64encode
|
||||
from itertools import tee
|
||||
|
||||
from django.apps import apps
|
||||
from django.db import connection
|
||||
@@ -155,7 +154,9 @@ class Field(RegisterLookupMixin):
|
||||
self.unique_for_date = unique_for_date
|
||||
self.unique_for_month = unique_for_month
|
||||
self.unique_for_year = unique_for_year
|
||||
self._choices = choices or []
|
||||
if isinstance(choices, collections.Iterator):
|
||||
choices = list(choices)
|
||||
self.choices = choices or []
|
||||
self.help_text = help_text
|
||||
self.db_index = db_index
|
||||
self.db_column = db_column
|
||||
@@ -405,7 +406,6 @@ class Field(RegisterLookupMixin):
|
||||
}
|
||||
attr_overrides = {
|
||||
"unique": "_unique",
|
||||
"choices": "_choices",
|
||||
"error_messages": "_error_messages",
|
||||
"validators": "_validators",
|
||||
"verbose_name": "_verbose_name",
|
||||
@@ -553,7 +553,7 @@ class Field(RegisterLookupMixin):
|
||||
# Skip validation for non-editable fields.
|
||||
return
|
||||
|
||||
if self._choices and value not in self.empty_values:
|
||||
if self.choices and value not in self.empty_values:
|
||||
for option_key, option_value in self.choices:
|
||||
if isinstance(option_value, (list, tuple)):
|
||||
# This is an optgroup, so look inside the group for
|
||||
@@ -848,14 +848,6 @@ class Field(RegisterLookupMixin):
|
||||
"""
|
||||
return smart_text(self._get_val_from_obj(obj))
|
||||
|
||||
def _get_choices(self):
|
||||
if isinstance(self._choices, collections.Iterator):
|
||||
choices, self._choices = tee(self._choices)
|
||||
return choices
|
||||
else:
|
||||
return self._choices
|
||||
choices = property(_get_choices)
|
||||
|
||||
def _get_flatchoices(self):
|
||||
"""Flattened version of choices tuple."""
|
||||
flat = []
|
||||
|
||||
Reference in New Issue
Block a user