Phurich.P
Phurich.P

Reputation: 1416

Django filter multiple value in the same column

I have set up the column where one of the table is called Establishment_Type

Now, I am trying to filter according to Establishment_Type.

Here is my view.py code

class ShopDetailAPIView(ListAPIView):
    serializer_class = ShopDetailSerializer
    def get_queryset(self):
        queryset = Shop.objects.all()
        type = self.request.query_params.get('type', None)
        type2 = self.request.query_params.get('type2', None)
        if type is not None and type2 is None:
            queryset = queryset.filter(Establishment_Type = type)
        elif type is not None and type2 is not None:
            queryset = queryset.filter(Q(Establishment_Type = type) | Q(Establishment_Type = type2))
        return queryset

In the url, I query by typing:

http://127.0.0.1:8000/shop/search/?type=Restaurant&type2=Petrol%20Station

Which only filter Establishment_Type = Restaurant but not include Establishment_Type = Petrol Station

Here is my urls.py within my app called shop:

urlpatterns = [

    url(r'^$', ShopListAPIView.as_view(), name = 'list' ),
    #####
    url(r'^create/$', ShopCreateAPIView.as_view(), name = 'create' ),
    url(r'^search/$', ShopDetailAPIView.as_view(), name = 'detail'),
]

Was my url for filtering 2 Establishment type wrong?

Do I need to change something in my code in order to filter 2 values in column Establishment_Type?

Upvotes: 3

Views: 2348

Answers (2)

Josh Correia
Josh Correia

Reputation: 4346

There is an even simpler way to achieve this using the django-filter package. Deep within the django-filter documentation, it mentions that you can use "a dictionary of field names mapped to a list of lookups".

Your code would be updated like so:

# views.py

from django_filters.rest_framework import DjangoFilterBackend

class ShopDetailAPIView(ListAPIView):
    queryset = Shop.objects.all()
    serializer_class = ShopDetailSerializer
    filter_backends = [DjangoFilterBackend]
    filter_fields = {
        'type': ["in", "exact"]
    }

Now in the URL you would add __in to the filter before supplying your list of parameters and it would work as you expect:

http://127.0.0.1:8000/shop/search/?type__in=Restaurant,Petrol%20Station

The django-filter documentation on what lookup filters are available is quite poor, but the in lookup filter is mentioned in the Django documentation itself.

Upvotes: 0

Phurich.P
Phurich.P

Reputation: 1416

Thanks @Thyrst' for advising me to use Establishment_Type__in=types

I have modify my code this way for my filter to work

class ShopDetailAPIView(ListAPIView):
    serializer_class = ShopDetailSerializer
    def get_queryset(self):
        queryset = Shop.objects.all()
        type = self.request.query_params.get('type', None)
        type = type.split(',')
        if type is not None:
            queryset = queryset.filter(Establishment_Type__in = type)
        return queryset

so type is now list, therefore when entered the url:

http://127.0.0.1:8000/shop/search/?type=Restaurant,Petrol%20Station

it filters according to Restaurant and Petrol Station.

it also works when entering just 1 value or more.

This is good for now but I feel like there might be a better way to implement this.

Upvotes: 1

Related Questions