24

I'm working with API made from Django rest framework, I am trying to make a filter to a JSON This is my serializers.py file

from rest_framework import serializers
from .models import Establecimiento,Categoria,Ciudad,Zona
import django_filters

class EstablecimientoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Establecimiento
        depth = 1

        fields =  ('nombre',
                   'ciudad',
                   'categoria',
                   'direccion',
                   'telefono',
                   'precioMinimo',
                   'precioMaximo',)

and this my views.py file

from rest_framework import viewsets
from .serializers import EstablecimientoSerializer, CategoriaSerializer
from models import *
from rest_framework import filters
from rest_framework import generics

class EstablecimientoViewSet(viewsets.ModelViewSet):
    queryset = Establecimiento.objects.all()
    serializer_class = EstablecimientoSerializer
    filter_fields = ('categoria',)

Then in the EstablecimientoViewSet class, I put a filter_fields = ('categoria',) to filter the url's API with the category field

If I add the filter to the query parameters, the result set does not change, it shows all data unfiltered.

...establecimiento?establecimiento=bar

How can I make this filter about this model?

3 Answers 3

33

You need to define filter backend and all related fields you're planning to filter on:

class EstablecimientoViewSet(viewsets.ModelViewSet):
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('categoria', 'categoria__titulo',)

example:

URL?categoria__titulo=Categoria 1
Sign up to request clarification or add additional context in comments.

3 Comments

This is not working for me. I am using Django 1.7. Are you sure Filter fields and backends work with ModelViewset too? This works perfectly with APIListview from generics.
in my case with DJango 1.7 i am getting a Meta.fields contains a field that isn't defined on this FilterSet also using modelviewsets
@psychok7, you have to add a comma to the end of the tuple filter_fields. Doing that fixed it for me.
7

it's also possible to supply your own Filter class, which may give you more options and flexibility

import sys, django_filters, json, io

class TaskFilter(django_filters.FilterSet):
    tag  = django_filters.CharFilter(name='tags__name', lookup_type='iexact')
    university = django_filters.NumberFilter(name='poster__university', lookup_type='exact')

    class Meta:
        model = Task
        fields = {
            'poster': ['exact'],
            'tasker': ['exact'],
            'status': ['exact'],
            'created': ['lt', 'gt']
        }

In this example I got filters

  1. poster = 1
  2. tasker = 115
  3. status = O
  4. created__lt=2015-09-22 17:39:01.184681 (so I can filter datetime by values LESS THEN)

  5. created__gt=2015-09-22 17:39:01.184681 (or GREATER THAN provided value)

Also I can hide foreign fields with custom filter fields, in this case it's tag & university. Plus I can provide comparison operator (lookup_type)

Sample request:

GET /api/v1/tasks/?offset=0&status=O&limit=100&university=1&ordering=-created&created__lt=2015-09-22 17:39:01.184681&tag=sport HTTP/1.1
Host: domain.com
Content-Type: application/json
Authorization: token 61cbd3c7c2656d4e24edb31f5923a86910c67b7c
User-Timezone: US/Pacific
Cache-Control: no-cache

Comments

2

For me, it works when I put the comma at the end of my filter_fields.

eg.

filter_fields = ('distribuidor',)

2 Comments

Looks like they're already doing that. Not sure your solution adds anything.
This worked for me. I had a tuple with only 1 item. Didn't realize I was missing a comma on my tuple.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.