web-dev-qa-db-fra.com

django rest framework filter

Je travaille avec une API faite à partir du framework Django rest, j'essaye de faire un filtre vers un JSON Ceci est mon fichier serializers.py

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',)

et ceci mon views.py fichier

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',)

Puis dans la classe EstablecimientoViewSet, je mets une filter_fields = ('categoria',) pour filtrer l'API de l'url avec le champ catégorie

Si j'ajoute le filtre aux paramètres de la requête, le jeu de résultats ne change pas, il affiche toutes les données non filtrées.

...establecimiento?establecimiento=bar

Comment puis-je faire ce filtre sur ce modèle?

23
user3236034

Vous devez définir le backend du filtre et tous les champs connexes sur lesquels vous prévoyez de filtrer:

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

exemple:

URL?categoria__titulo=Categoria 1
32
mariodev

il est également possible de fournir votre propre classe Filter, ce qui peut vous donner plus d'options et de flexibilité

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']
        }

Dans cet exemple, j'ai des filtres

  1. affiche = 1
  2. tasker = 115
  3. statut = O
  4. created__lt = 2015-09-22 17: 39: 01.184681 (donc je peux filtrer datetime par des valeurs MOINS ALORS)

  5. created__gt = 2015-09-22 17: 39: 01.184681 (ou PLUS GRAND QUE la valeur fournie)

Je peux également masquer les champs étrangers avec des champs de filtre personnalisés, dans ce cas, c'est tagniversité. De plus, je peux fournir un opérateur de comparaison (lookup_type)

Demande d'échantillon:

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
7
DmitrySemenov

Pour moi, cela fonctionne quand je mets la virgule à la fin de mes filter_fields.

par exemple.

filter_fields = ('distribuidor',)
3
Thiago Soares