Skip to content

Commit

Permalink
Allowed using dictionaries for grouped choices (#1668)
Browse files Browse the repository at this point in the history
Co-authored-by: Carlton Gibson <carlton.gibson@noumenal.es>
  • Loading branch information
saevarom and carltongibson committed Aug 2, 2024
1 parent 376d443 commit 23be051
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
14 changes: 14 additions & 0 deletions django_filters/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@
)
from .utils import get_model_field, label_for_filter

try:
from django.utils.choices import normalize_choices
except ImportError:
DJANGO_50 = False
else:
DJANGO_50 = True


__all__ = [
"AllValuesFilter",
"AllValuesMultipleFilter",
Expand Down Expand Up @@ -479,6 +487,12 @@ def __init__(self, choices=None, filters=None, *args, **kwargs):
if filters is not None:
self.filters = filters

if isinstance(self.choices, dict):
if DJANGO_50:
self.choices = normalize_choices(self.choices)
else:
raise ValueError("Django 5.0 or later is required for dict choices")

all_choices = list(
chain.from_iterable(
[subchoice[0] for subchoice in choice[1]]
Expand Down
18 changes: 18 additions & 0 deletions tests/test_filters.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import inspect
import unittest
from collections import OrderedDict
from datetime import date, datetime, time, timedelta
from unittest import mock

import django
from django import forms
from django.test import TestCase, override_settings
from django.utils import translation
Expand Down Expand Up @@ -1105,6 +1107,22 @@ def test_choices_with_optgroups_dont_mistmatch(self):
choices=[("group", ("a", "a")), ("b", "b")], filters={"a": None, "b": None}
)

@unittest.skipUnless(django.VERSION >= (5, 0), "Django 5.0 introduced new dictionary choices option")
def test_grouped_choices_as_dictionary(self):
DateRangeFilter(
choices={"group": {"a": "a", "b": "b"}}, filters={"a": None, "b": None}
)

@unittest.skipUnless(django.VERSION <= (4, 2), "Django 5.0 introduced new dictionary choices option")
def test_grouped_choices_error(self):
with self.assertRaisesMessage(
ValueError,
"Django 5.0 or later is required for dict choices"
):
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:
Expand Down

0 comments on commit 23be051

Please sign in to comment.