Feature: Supports OR operations between fields
mani098 opened this issue · 1 comments
Can we have an option to support OR operation to filter by value in multiple fields specified in URL
For example: /api/companies?search_fields=department__name,department__alias&search_value=Accounting
This will return queryset if Accounting
present in either of the fields specified in the URL dynamically.
Reference:
from django.db.models import Q
qs = Company.objects.filter(Q(department__name=Accouting) | Q(department__alias=Accounting))
Hi @mani098, there are already a few options available.
If hardcoding the value for search_fields
is acceptable, then you can use Filter.method
. eg,
class MyFilterset(filters.FilterSet):
search = filters.CharFilter(method='filter_search')
def filter_search(self, qs, name, value):
return qs.filter(Q(department__name=value) | Q(department__alias=value))
If you need to allow users to specify the fields, then you'll need to create a custom filter class. Something like the below should work. Keep in mind that I haven't actually ran this, so it's likely you'll need to fix it:
class SearchWidget(django_filters.widgets.SuffixedMultiWidget):
suffixes = ['fields', 'value']
class SearchField(forms.MultiValueField):
widget = SearchWidget
def __init__(self, fields=None, *args, **kwargs):
if fields is None:
fields = (forms.CharField(), forms.CharField())
super(SearchField, self).__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
return [data_list[0].split(','), data_list[1]]
return None
class SearchFilter(filters.Filter):
field_class = SearchField
def filter(self, qs, value):
fields, value = value
return qs.filter(reduce(operator.or_,
Q(**{name: value}) for name in fields
))