-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
ModelMultipleChoiceFilter's custom method gets called even when field is not filtered on #1625
Comments
Continuing from #1622 Thanks Carlton.
In my case, every filter on the filterset is present in class Filter:
def filter(self, qs, value):
if value in EMPTY_VALUES:
return qs After further digging, it appears that filters with and without custom methods are behaving the same way (showing up in
To me, this is the issue. I ran into a similar problem when implementing an empty values filter. If it can be updated so that non-submitted filters do not show up in class BaseFilterSet:
def filter_queryset(self, queryset):
for name in self.form.cleaned_data.keys() & self.request.query_params.keys():
value = self.form.cleaned_data[name]
queryset = self.filters[name].filter(queryset, value)
...
return queryset |
Update:
for name in self.form.changed_data:
for name in self.request.query_params:
for name in self.form.data: So it seems we need to use a subset of keys that are in both: for name in self.form.cleaned_data.keys() & self.request.query_params.keys():
for name in self.form.cleaned_data.keys() & self.form.data.keys(): |
So that's what I'm expecting (without cracking open the debugger). Can you put the failing case in a test case against Django-filter's test suite? That makes it much easier to see exactly what you mean, rather than prose descriptions, where I can't see 100% what's going on. |
Understood - yes, I'll do my best to write something using your test suite. In the meantime, I have an example repo with tests that demonstrate the issue, if that's helpful. |
I noticed something similar in a failing test in our app just now when upgrading from django-filter 23.2 to 23.3 - a callable I suspect 6119d45 but the diff looks fine to me. For reference we're (still) on Django 3.2.x so the 5.x specific changes in that commit shouldn't apply to us |
@craigds A test case against django-filter's test suite would be handy. |
@johncmacy This may be resolved in the new v24.2. If you'd like to give that a run and confirm that would be great. |
Hi @carltongibson, I upgraded to v24.2, and am still getting the same behavior as before. |
@johncmacy Thanks for confirming. It's not the same issue then ✅ |
@johncmacy Just re-reading this, I still need some time to sit down with the debugger, but if I were writing this myself I'd would automatically handle the none value before filtering, so I'm suspecting the answer is likely to be That's just how it works. |
Ok, thanks for following up on this @carltongibson. It's not a deal-breaker, we can work around it. |
Discussed in #1622
Converting to an issue to investigate.
Originally posted by johncmacy November 10, 2023
Hi,
I have a FilterSet with a ModelMultipleChoiceFilter that has a custom method:
After getting some unexpected results, I found out that the custom method is getting called even when the field is not passed as a query param. For example, requests to
/api/book
return an empty list[]
.After digging into it a bit, it seems that every filter gets called regardless if it's passed as a query param. Normally this is fine because they get an empty value and it doesn't apply any filtering. However, when a custom method is supplied, it gets called with
<QuerySet []>
as thevalue
. So in the example above, it filters books by publisher in[]
, which results in the empty result set.I got around it with:
However, I didn't expect the method to get called in the first place, since the request didn't have a "publisher" query param. Am I missing something in the filter configuration that would prevent it from being called in the first place?
Thanks!
The text was updated successfully, but these errors were encountered: