I was using CSVWidget with a CharFilter in the pre 1.x days, but I'm upgrading and that combination no longer works. I can't find any docs or recommendations on what to switch to. I want to accept a single value or multiple values separated by commas
Try something like:
class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
pass
I spent some time myself running into this problem, and I think @carltongibson solution definitely helps some issues for me.
I was attempting to do something like:
class TestListFilter(Filter):
field_class = forms.CharField
def filter(self, qs, value):
actual_filter = fields.Lookup(value, 'in')
from pprint import pprint
pprint(value)
pprint(actual_filter)
return qs
class BaseModelFilter(filters.FilterSet):
id__in = TestListFilter(name='id', lookup_expr='in', widget=widgets.CSVWidget)
Using DRF & a url of: ?id__in=a,b,c
However it seems as though using widget=widgets.CSVWidget
actually casts the list as a string somehow?
Printing the value of the filter results in "['a', 'b', 'c']"
the actual_filter has the quotes as well
Lookup(value="['a', 'b', 'c']", lookup_type='in')
Per the recommendation provided I switch things up to:
class UUIDInFilter(filters.BaseInFilter, filters.UUIDFilter):
pass
class BaseModelFilter(filters.FilterSet):
id = UUIDInFilter(name='id', lookup_expr='in')
And then I was able to use ?id=3e543ed4-9b90-403d-8f40-048297a9ac31,6bf953eb-3ac3-4ea1-8ce5-9f84dd392246
to get the expected results.
The "List as string" thing kind of seems like a bug or at least some doc changes maybe? I'm pretty unfamiliar with how the underlying functionality works though. Maybe it's just use error =)
CSVWidget
is correctly returning a list of values, however CharField.clean()
is coercing the list back into a text value, hence "['1', '2', '3']"
. It's not sufficient to pass CSVWidget
to the filter - the form field needs to be overridden to accept a list of values.
The easiest way to get the correct field behavior is to mixin the BaseCSVFilter
, as it properly constructs a form field that accepts a list of values.
Most helpful comment
CSVWidget
is correctly returning a list of values, howeverCharField.clean()
is coercing the list back into a text value, hence"['1', '2', '3']"
. It's not sufficient to passCSVWidget
to the filter - the form field needs to be overridden to accept a list of values.The easiest way to get the correct field behavior is to mixin the
BaseCSVFilter
, as it properly constructs a form field that accepts a list of values.