From d693a5947389ef018058fe8226245e141a2b0f0f Mon Sep 17 00:00:00 2001 From: Florent Lebreton Date: Wed, 29 Nov 2023 19:00:38 +0100 Subject: [PATCH] Allow choices to contains optgroups in DateRangeFilter (#1621) --- django_filters/filters.py | 11 ++++++++++- tests/test_filters.py | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/django_filters/filters.py b/django_filters/filters.py index 3a494c15..6ec94624 100644 --- a/django_filters/filters.py +++ b/django_filters/filters.py @@ -1,5 +1,6 @@ from collections import OrderedDict from datetime import timedelta +from itertools import chain from django import forms from django.core.validators import MaxValueValidator @@ -478,7 +479,15 @@ def __init__(self, choices=None, filters=None, *args, **kwargs): if filters is not None: self.filters = filters - unique = set([x[0] for x in self.choices]) ^ set(self.filters) + all_choices = list( + chain.from_iterable( + [subchoice[0] for subchoice in choice[1]] + if isinstance(choice[1], (list, tuple)) # This is an optgroup + else [choice[0]] + for choice in self.choices + ) + ) + unique = set(all_choices) ^ set(self.filters) assert not unique, ( "Keys must be present in both 'choices' and 'filters'. Missing keys: " "'%s'" % ", ".join(sorted(unique)) diff --git a/tests/test_filters.py b/tests/test_filters.py index 0b5f9efc..290fbc13 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1100,6 +1100,11 @@ def test_choices_and_filters_mismatch(self): with self.assertRaisesMessage(AssertionError, msg): DateRangeFilter(choices=[("a", "a")], filters={"b": None}) + def test_choices_with_optgroups_dont_mistmatch(self): + DateRangeFilter( + choices=[("group", ("a", "a")), ("b", "b")], filters={"a": None, "b": None} + ) + def test_filtering_for_this_year(self): qs = mock.Mock(spec=["filter"]) with mock.patch("django_filters.filters.now") as mock_now: