RVE
RVE

Reputation: 348

Create OR filter with django_filters

I want to create an OR filter in my django_filters. All filters with perfect, except my productname.

I have a searchbox that needs to search for a productname in the column name_nl, name_en and name_fr.

How can I create an or filter with Django_filter?

class ProductFilter(django_filters.FilterSet):
status = django_filters.CharFilter(name='productvariant__status_id', lookup_type='exact')
productname = django_filters.CharFilter(name='name_nl', lookup_type='icontains')

class Meta:
    model = Product
    fields = {
        'productname': ['icontains'],
        'status': ['exact']
    }

Upvotes: 4

Views: 3624

Answers (3)

fpghost
fpghost

Reputation: 2954

Since 1.x version, MethodFilter was removed. Now it looks like:

import django_filters
from django.db.models import Q

from app.models import User

class UserFilter(django_filters.FilterSet):
    q = filters.CharFilter(method='filter_q')

    def filter_q(self, qs, name, value):
        return qs.filter(
            Q(last_name__icontains=value) | Q(first_name__icontains=value) | Q(email__icontains=value)
        )


and for the view

from django_filters.views import FilterView

from .filters import UserFilter

class AgentListView(ClassRequiredMixin, FilterView):

    filterset_class = UserFilter

Note that if you're using DRF then filterset_class in 2.x is named filter_class in 1.x

from django_filters import rest_framework as filters

class AgentListViewSet(viewsets.ModelViewSet):
    filter_backends = (filters.DjangoFilterBackend, )
    filter_class = UserFilter

Upvotes: 4

Ceebs
Ceebs

Reputation: 133

You can do it like this.

import django_filters
from django.db.models import Q

from app.models import User

class UserFilter(django_filters.FilterSet):

    q = django_filters.MethodFilter()

    class Meta:
        model = User
        fields = []

    def filter_q(self, queryset, value):
        return queryset.filter(
            Q(last_name__icontains=value) | Q(first_name__icontains=value) | Q(email__icontains=value)
        )

Then make a generic view.

from django_filters.views import FilterView

from .filters import UserFilter

class AgentListView(ClassRequiredMixin, FilterView):

    filterset_class = UserFilter

For your template see http://django-filter.readthedocs.org/en/latest/usage.html#the-template

Upvotes: 3

cdvv7788
cdvv7788

Reputation: 2099

You can use Q() objects.

From the documentation:

Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

Gives something like:

SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

Upvotes: -4

Related Questions