Open pajowu opened 1 month ago
Hmmm. Prior to the change the default was a dict
which has the same behaviour when passed to value_from_datadict()
:
>>> from django.utils.datastructures import MultiValueDict
>>> d = MultiValueDict()
>>> d.get("prices")
>>> {}.get("prices")
i.e. data
should be None
in both cases no? 🤔
I don't fully understand your comment, but just in case:
The problem is not the .get
-Method, but the self.data
attribute getting set which is then used further in render_option
: https://github.com/carltongibson/django-filter/blob/3656174bd90d20f3d916fd98b6476c270013b681/django_filters/widgets.py#L59-L65
Urlencode then encodes the lists which MultiValueDict returns as their string-representation (as seen in the test output)
>>> from django.utils.http import MultiValueDict, urlencode
>>>
>>> d = MultiValueDict()
>>> d['prices'] = ''
>>> urlencode(d)
'prices=%5B%27%27%5D'
>>>
>>>
>>> d = {}
>>> d["prices"] = ""
>>> urlencode(d)
'prices='
Ok, so we'll likely have to cast to a dict there. The data should be a multidict, so LinkWidget should handle that.
Good spot.
Fancy making a PR with the regression test and tweak?
@pajowu Actually, it looks like we want a QueryDict in this case (which provides the urlencode()
method.
Do you fancy trying the change from #1634 using that to see the effect?
(Possibly we can drop the try block, since data should no longer be a dict in any case)
1634 introduced using a
MultiValueDict
as the default empty value for the form data. This however broke using LinkWidget. If the FilterSet is initialised with a false-ydata
attribute, theFilterSet
s data attribute is set to an emptyMultiValueDict
. This gets passed toLinkWidget
svalue_from_datadict
, which then sets itsself.data
attribute to it. This leads toLinkWidget.render_option
passing aMultiValueDict
todjango.utils.http.urlencode
which then renders the option values as lists (?price=%5B%27test-val1%27%5D
, i.e.?price=['test-val1']
, instead of?price=test-val1
for an empty option in the example below).fails as follows: