Django drf filtering

首先,rest framework列表视图默认返回的是一个model的全部queryset,但是我们需要的结果往往只是一个子集,最简单过滤任意GenericAPIView子视图的queryset的方法就是重写.get_queryset(),重写这个方法可以制定视图返回的queryset

1.根据当前用户进行过滤

        根据请求值进行过滤

def get_queryset(self):
        """
        This view should return a list of all the purchases
        for the currently authenticated user.
        """
        user = self.request.user
        return Purchase.objects.filter(purchaser=user)

2.根据URL进行过滤

        url('^purchases/(?P.+)/$', PurchaseList.as_view())——则我们应在view中返回基于url的username参数进行过滤结果

def get_queryset(self):
        """
        This view should return a list of all the purchases for
        the user as determined by the username portion of the URL.
        """
        username = self.kwargs['username']  #获得传入参数值
        return Purchase.objects.filter(purchaser__username=username)

3.根据查询参数进行过滤,只有在URL中包含username参数时,才过滤queryset:

def get_queryset(self):
        """
        Optionally restricts the returned purchases to a given user,
        by filtering against a `username` query parameter in the URL.
        """
        queryset = Purchase.objects.all()
        username = self.request.query_params.get('username', None)
        if username is not None:
            queryset = queryset.filter(purchaser__username=username)
        return queryset

4.通用过滤

        全局配置

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

5.Django过滤后端

        django-filter库包含一个为rest framework提供可制定字段过滤的DjangoFilterBackend类

pip install django-filter

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
如果你正在使用 browsable API或 admin API,你还需要安装django-crispy-forms,通过使用Bootstarp3渲染来提高filter form在浏览器中的展示效果。

pip install django-crispy-forms

5.1指定category和in_stock为筛选字段

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('category', 'in_stock')

#查询结果集、序列化结果、过滤

5.2 指定FilterSet:对于更高级的过滤要求,可以指定在view中使用Filter类

定义一个过滤类:

        

class ProductFilter(django_filters.rest_framework.FilterSet):
    min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
    max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'min_price', 'max_price']



class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_class = ProductFilter


#field_name(必选):模型类的属性
#lookup_expr(可选):判断条件

#iexact:表示精确匹配, 并且忽略大小写
#icontains:表示模糊查询(包含),并且忽略大小写
#exact:表示精确匹配
#gte:用于规定范围,大于等于
#lte: 用于范围,小于等于

django-filter跨越关系,假设每个产品都有Manufacture模型的外键,创建过滤器使用Manufacture名称过滤

import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import generics

class ProductFilter(django_filters.rest_framework.FilterSet):
    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'manufacturer__name']

可以进行如下查询:http://example.com/api/products?manufacturer__name=foo

class ProductFilter(django_filters.rest_framework.FilterSet):
    manufacturer = django_filters.CharFilter(name="manufacturer__name")

    class Meta:
        model = Product
        fields = ['category', 'in_stock', 'manufacturer']

#filter类可以引用外键表,对其进行筛选

过滤器可以很好的使我们获得需要的相应内容

你可能感兴趣的:(django,python,后端)