From 03116531ac20a7c47a57d42ce9b56e93dce28d39 Mon Sep 17 00:00:00 2001 From: Craig de Stigter Date: Wed, 27 Mar 2024 22:45:15 +1300 Subject: [PATCH] Fixed setting callable choices on Django <5.0. (#1648) * Failing test for ChoiceField eagerly evaluating choices * Fixed regression in choices setter for Django 4.2. --------- Co-authored-by: Carlton Gibson --- django_filters/fields.py | 8 ++++---- tests/test_fields.py | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/django_filters/fields.py b/django_filters/fields.py index 3a343651..d6ac79cb 100644 --- a/django_filters/fields.py +++ b/django_filters/fields.py @@ -275,13 +275,13 @@ def choices(self): def choices(self, value): if DJANGO_50: value = self.iterator(self, value) + # Simple `super()` syntax for calling a parent property setter is + # unsupported. See https://github.com/python/cpython/issues/59170 + super(ChoiceIteratorMixin, self.__class__).choices.__set__(self, value) else: super()._set_choices(value) value = self.iterator(self, self._choices) - - # Simple `super()` syntax for calling a parent property setter is - # unsupported. See https://github.com/python/cpython/issues/59170 - super(ChoiceIteratorMixin, self.__class__).choices.__set__(self, value) + self._choices = self.widget.choices = value # Unlike their Model* counterparts, forms.ChoiceField and forms.MultipleChoiceField do not set empty_label diff --git a/tests/test_fields.py b/tests/test_fields.py index d30de894..9553bbbd 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -12,6 +12,7 @@ from django_filters.fields import ( BaseCSVField, BaseRangeField, + ChoiceField, DateRangeField, DateTimeRangeField, IsoDateTimeField, @@ -58,6 +59,14 @@ def test_clean(self): self.assertIsNone(f.clean([])) +class ChoiceFieldTests(TestCase): + def test_callable_choices_is_lazy(self): + def choices(): + self.fail("choices should not be called during initialization") + + ChoiceField(choices=choices) + + class DateRangeFieldTests(TestCase): def test_field(self): f = DateRangeField()