-
Notifications
You must be signed in to change notification settings - Fork 130
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
Combining filters for multi-valued relationships with AND
#351
Comments
I ended up adding a mixin that overwrites the from django.db.models import QuerySet
from django_filters.constants import EMPTY_VALUES
from rest_framework_filters import FilterSet
class FilterSetMixin:
def filter_queryset(self, queryset):
"""
Overrides the basic method, so that instead of iterating over the queryset with multiple `.filter()`
calls, one for each filter, it accumulates the lookup expressions and applies them all in a single
`.filter()` call - to filter with an explicit "AND" in many to many relationships.
"""
filter_kwargs = {}
for name, value in self.form.cleaned_data.items():
if value not in EMPTY_VALUES:
lookup = '%s__%s' % (self.filters[name].field_name, self.filters[name].lookup_expr)
filter_kwargs.update({lookup: value})
queryset = queryset.filter(**filter_kwargs)
assert isinstance(queryset, QuerySet), \
"Expected '%s.%s' to return a QuerySet, but got a %s instead." \
% (type(self).__name__, name, type(queryset).__name__)
queryset = self.filter_related_filtersets(queryset)
return queryset
class BlogFilterSet(FilterSetMixin, FilterSet):
class Meta:
model = Blog
fields = {
'entry__headline': ['contains'],
'entry__pub_date': ['year__exact']
}
class BlogViewSet(viewsets.ModelViewSet):
serializer_class = BlogSerializer
filter_backends = (RestFrameworkFilterBackend, )
filterset_class = BlogFilterSet It feels like this should be the default behavior. But maybe I'm missing something. |
Is there are any better way? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In my DRF project, I'm trying to implement filtering for multi-valued relationships that combines filters with logical
AND
s, like in:a)
Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)
instead of
OR
like in:b)
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
The following results in b):
Is there a way to get a) without specifying the filter explicitly? If no, could someone provide an example for the explicit filter based on the one I provided?
Thank you.
The text was updated successfully, but these errors were encountered: