Skip to content

Commit

Permalink
fix(QueryArrayWidget): value_from_datadict should not mutate input data
Browse files Browse the repository at this point in the history
  • Loading branch information
legau committed Oct 27, 2022
1 parent 06472fc commit a0ab054
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
1 change: 1 addition & 0 deletions django_filters/widgets.py
Expand Up @@ -246,6 +246,7 @@ class QueryArrayWidget(BaseCSVWidget, forms.TextInput):

def value_from_datadict(self, data, files, name):
if not isinstance(data, MultiValueDict):
data = data.copy()
for key, value in data.items():
# treat value as csv string: ?foo=1,2
if isinstance(value, str):
Expand Down
37 changes: 33 additions & 4 deletions tests/test_filtering.py
Expand Up @@ -13,6 +13,7 @@
from django_filters.filters import (
AllValuesFilter,
AllValuesMultipleFilter,
BaseInFilter,
CharFilter,
ChoiceFilter,
DateFromToRangeFilter,
Expand All @@ -30,6 +31,7 @@
TypedMultipleChoiceFilter,
)
from django_filters.filterset import FilterSet
from django_filters.widgets import QueryArrayWidget

from .models import (
STATUS_CHOICES,
Expand Down Expand Up @@ -1972,10 +1974,10 @@ class Meta:

class MiscFilterSetTests(TestCase):
def setUp(self):
User.objects.create(username="alex", status=1)
User.objects.create(username="jacob", status=2)
User.objects.create(username="aaron", status=2)
User.objects.create(username="carl", status=0)
User.objects.create(username="alex", last_name="johnson", status=1)
User.objects.create(username="jacob", last_name="johnson", status=2)
User.objects.create(username="aaron", last_name="white", status=2)
User.objects.create(username="carl", last_name="black", status=0)

def test_filtering_with_declared_filters(self):
class F(FilterSet):
Expand Down Expand Up @@ -2051,3 +2053,30 @@ class Meta:
f = F({"status": "2"}, queryset=qs)
self.assertEqual(len(f.qs), 2)
self.assertEqual(f.qs.count(), 2)

def test_filtering_with_widgets(self):

class CharInFilter(BaseInFilter, CharFilter):
pass

class F(FilterSet):
last_name = CharInFilter(widget=QueryArrayWidget)
username = CharInFilter()

class Meta:
model = User
fields = ["last_name", "username"]

qs = User.objects.all()

f = F({"last_name": ["johnson"]}, queryset=qs)
self.assertQuerysetEqual(f.qs, ["alex", "jacob"], lambda o: o.username, ordered=False)

f = F({"last_name": ["johnson"], "username": "carl"}, queryset=qs)
self.assertQuerysetEqual(f.qs, [], lambda o: o.username, ordered=False)

f = F({"last_name": ["johnson"], "username": "jacob"}, queryset=qs)
self.assertQuerysetEqual(f.qs, ["jacob"], lambda o: o.username, ordered=False)

f = F({"last_name": ["johnson", "white"], "username": "jacob, carl, aaron"}, queryset=qs)
self.assertQuerysetEqual(f.qs, ["jacob", "aaron"], lambda o: o.username, ordered=False)

0 comments on commit a0ab054

Please sign in to comment.