Django Rest Framework 过滤器

24

我正在使用由Django Rest Framework创建的API进行工作,我试图对JSON进行过滤。这是我的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',)

这是我的views.py文件。

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',)
然后在EstablecimientoViewSet类中,我放置了一个filter_fields=('categoria',)来使用分类字段过滤url的API。 如果我将过滤器添加到查询参数中,则结果集不会更改,它会显示所有未经过滤的数据。
...establecimiento?establecimiento=bar

我要如何让这个过滤器与这个模型相关联?

3个回答

33

您需要定义筛选器后端和所有相关的筛选字段,这些字段是您计划进行筛选的。

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

例子:

URL?categoria__titulo=Categoria 1

非常感谢您的帮助:D - user3236034
5
这对我没用。我正在使用Django 1.7版本。你确定Filter fields和backends也适用于ModelViewset吗?在generics的APIListview中可以完美地工作。 - iankit
4
在我的情况下,使用Django 1.7版本,我遇到了Meta.fields contains a field that isn't defined on this FilterSet的错误提示,同时也在使用modelviewsets。 - psychok7
18
@psychok7,你需要在元组 filter_fields 的末尾添加逗号。这样做对我来说已经解决了问题。 - imagineerThat

7

您也可以提供自己的过滤器类,这可能会为您提供更多选项和灵活性。

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

在这个例子中,我得到了一些过滤器。
  1. poster = 1
  2. tasker = 115
  3. status = O
  4. created__lt=2015-09-22 17:39:01.184681(因此我可以通过小于提供的值来过滤日期时间)

  5. created__gt=2015-09-22 17:39:01.184681(或者大于提供的值)

此外,我可以使用自定义过滤字段隐藏外部字段,在这种情况下是taguniversity。另外,我可以提供比较运算符(lookup_type)。
示例请求:
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

2
对我来说,在我的filter_fields末尾加上逗号是有效的。
例如:
filter_fields = ('distribuidor',)

看起来他们已经在做那件事了。不确定你的解决方案是否有所增加。 - David T. Macknet
这对我有用。我有一个只有1个项目的元组。没有意识到我的元组缺少逗号。 - bradleygsmith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接