From 2f73b527dda6683868fac2791f7f07ccb01ea0d9 Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Fri, 25 Jul 2014 19:20:00 +0200 Subject: [PATCH] Fixed #23098 -- Checked that lazy choices are not evaluated too soon Thanks Matthieu Agopian for the report. --- django/db/models/fields/__init__.py | 10 ++++++---- tests/model_fields/tests.py | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 56c25f0045..99bb948184 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -730,10 +730,12 @@ class Field(RegisterLookupMixin): """Returns choices with a default blank choices included, for use as SelectField choices for this field.""" blank_defined = False - for choice, __ in self.choices: - if choice in ('', None): - blank_defined = True - break + named_groups = self.choices and isinstance(self.choices[0][1], (list, tuple)) + if not named_groups: + for choice, __ in self.choices: + if choice in ('', None): + blank_defined = True + break first_choice = (blank_choice if include_blank and not blank_defined else []) diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index b33314bfd3..87236c31d5 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -416,6 +416,13 @@ class ValidationTest(test.TestCase): f = models.CharField(choices=[('', '<><>'), ('a', 'A')]) self.assertEqual(f.get_choices(True), [('', '<><>'), ('a', 'A')]) + def test_charfield_get_choices_doesnt_evaluate_lazy_strings(self): + # Regression test for #23098 + # Will raise ZeroDivisionError if lazy is evaluated + lazy_func = lazy(lambda x: 0/0, int) + f = models.CharField(choices=[(lazy_func('group'), (('a', 'A'), ('b', 'B')))]) + self.assertEqual(f.get_choices(True)[0], ('', '---------')) + def test_choices_validation_supports_named_groups(self): f = models.IntegerField( choices=(('group', ((10, 'A'), (20, 'B'))), (30, 'C')))