Ticket #13181: as_actual_callable.diff

File as_actual_callable.diff, 2.6 KB (added by Klaas van Schelven, 10 years ago)
  • django/forms/fields.py

    diff --git a/django/forms/fields.py b/django/forms/fields.py
    index 621d380..a9dca5c 100644
    a b class ChoiceField(Field): 
    757757
    758758    def __deepcopy__(self, memo):
    759759        result = super(ChoiceField, self).__deepcopy__(memo)
    760         result._choices = copy.deepcopy(self._choices, memo)
     760
     761        if hasattr(self, '_choices_as_callable'):
     762            result_choices = self._choices_as_callable()
     763        else:
     764            result_choices = copy.deepcopy(self._choices, memo)
     765
     766        result._set_choices(result_choices)
     767
    761768        return result
    762769
    763770    def _get_choices(self):
    class ChoiceField(Field): 
    767774        # Setting choices also sets the choices on the widget.
    768775        # choices can be any iterable, but we call list() on it because
    769776        # it will be consumed more than once.
    770         self._choices = self.widget.choices = list(value)
     777        if callable(value):
     778            self._choices = value()
     779            self._choices_as_callable = value
     780        else:
     781            self._choices = self.widget.choices = list(value)
     782
    771783
    772784    choices = property(_get_choices, _set_choices)
    773785
  • tests/regressiontests/forms/tests/fields.py

    diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
    index 3fe2cd2..945a2ae 100644
    a b def fix_os_paths(x): 
    4949    else:
    5050        return x
    5151
    52 
    5352class FieldsTests(SimpleTestCase):
    5453
    5554    def assertWidgetRendersTo(self, field, to):
    class FieldsTests(SimpleTestCase): 
    893892        f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
    894893        self.assertEqual(None, f.clean(''))
    895894
     895    def test_choicefield_callable(self):
     896        choices = lambda: [('J', 'John'), ('P', 'Paul')]
     897        f = ChoiceField(choices=choices)
     898        self.assertEqual(u'J', f.clean('J'))
     899     
     900    def test_choicefield_callable_may_evaluate_to_different_values(self):
     901        choices = []
     902        def choices_as_callable():
     903            return choices
     904
     905        class ChoiceFieldForm(Form):
     906            choicefield = ChoiceField(choices=choices_as_callable)
     907
     908        choices = [('J', 'John'), ('P', 'Paul')]
     909        form = ChoiceFieldForm()
     910        self.assertTrue("John" in form.as_p())
     911
     912        choices = [('M', 'Marie'),]
     913        form = ChoiceFieldForm()
     914        self.assertTrue("Marie" in form.as_p())
     915
    896916    # NullBooleanField ############################################################
    897917
    898918    def test_nullbooleanfield_1(self):
Back to Top