diff --git a/django_filters/widgets.py b/django_filters/widgets.py index f5c99b11..49f64a85 100644 --- a/django_filters/widgets.py +++ b/django_filters/widgets.py @@ -6,9 +6,9 @@ from django import forms from django.db.models.fields import BLANK_CHOICE_DASH from django.forms.utils import flatatt +from django.http import QueryDict from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str -from django.utils.http import urlencode from django.utils.safestring import mark_safe from django.utils.translation import gettext as _ @@ -56,13 +56,13 @@ def render_option(self, name, selected_choices, option_value, option_label): option_value = force_str(option_value) if option_label == BLANK_CHOICE_DASH[0][1]: option_label = _("All") - data = self.data.copy() + + data = QueryDict(mutable=True) + data.update(self.data) data[name] = option_value + selected = data == self.data or option_value in selected_choices - try: - url = data.urlencode() - except AttributeError: - url = urlencode(data) + url = data.urlencode() return self.option_string() % { "attrs": selected and ' class="selected"' or "", "query_string": url, diff --git a/tests/test_widgets.py b/tests/test_widgets.py index f50cc1be..27dd9967 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -1,6 +1,6 @@ from django.forms import NumberInput, Select, TextInput from django.test import TestCase - +from django.utils.datastructures import MultiValueDict from django_filters.widgets import ( BaseCSVWidget, BooleanWidget, @@ -143,6 +143,25 @@ def test_widget_with_blank_choice(self): """, ) + def test_widget_multivaluedict(self): + choices = ( + ("", "---------"), + ("test-val1", "test-label1"), + ("test-val2", "test-label2"), + ) + + w = LinkWidget(choices=choices) + w.value_from_datadict(MultiValueDict(), {}, "price") + self.assertHTMLEqual( + w.render("price", ""), + """ + """, + ) + def test_widget_value_from_datadict(self): w = LinkWidget() data = {"price": "test-val1"}