Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CharFilter(widget=CSVWidget) no longer works in 1.x #727

Closed
jwineinger opened this issue May 24, 2017 · 3 comments
Closed

CharFilter(widget=CSVWidget) no longer works in 1.x #727

jwineinger opened this issue May 24, 2017 · 3 comments

Comments

@jwineinger
Copy link

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

@carltongibson
Copy link
Owner

Try something like:

class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
     pass

@mwisner
Copy link

mwisner commented Sep 17, 2017

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 =)

@rpkilby
Copy link
Collaborator

rpkilby commented Sep 21, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants