DRF(十一):过滤排序

过滤Filtering

使用场景:在获取所有或者部分数据的时候使用。SearchFilter和OrderingFilter只能在继承GenericVIew及其子类中的视图函数中使用,因为只有GenericVIew有filter_backends属性。

第一种:SearchFilter类

在用SearchFilter类过滤时要注意postman中输入的接口地址最后的格式为?search=xxx。前面必须是?search=,后面是过滤内容。SearchFilter:支持模糊查询。
filter_backends = [SearchFilter,] # 配置过滤类
search_fields = [‘name’,“price”] #配置要过滤的字段

from rest_framework.filters import SearchFilter

class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
# 在视图函数中注册和添加过滤的字段
    filter_backends = [SearchFilter,] # 配置过滤类
    search_fields = ['name'"price"] #配置要过滤的字段
    
# 在postman中输入接口地址
http://127.0.0.1:8000/book/?search=雷雨
http://127.0.0.1:8000/book/?search=15

第二种:排序OrderingFilter类

filter_backends = [OrderingFilter, ]
排序字段放在ordering属性中: ordering_fields = [‘price’,‘id’]

from rest_framework.filters import OrderingFilter

class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 配置排序类
    filter_backends = [OrderingFilter, ]
    # 配置要排序的字段
    # ordering_fields = ['price'] # http://127.0.0.1:8000/books/?ordering=-price 按price降序排列
    ordering_fields = ['price','id'] 
    #http://127.0.0.1:8000/books/?ordering=-price,-id 按price降序排列,如果price一样,再按id的降序排列
例:既有排序,又有过滤

from rest_frajiyoumework.filters import SearchFilter, OrderingFilter
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 配置排序类
    filter_backends = [SearchFilter,OrderingFilter, ]
    #配置要过滤的字段
    search_fields=['name',]
    # 配置要排序的字段
    ordering_fields = ['price']  #http://127.0.0.1:8000/books/?search=记&ordering=-price  查询名字中带记的并且按价格降序排列

第三种:第三方过滤类使用django-filter

1.下载:pip3 install django-filter
2.在setting.py中注册django-filter应用

INSTALLED_APPS = [
    ...
    'django_filters',  # 需要注册应用,
]

3.全局配置

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

4.使用django-filter导入DjangoFilterBackend
filter_backends = [DjangoFilterBackend] # 局部配置
过滤字段放在属性filterset_fields中: filterset_fields=[‘name’,‘price’]

from django_filters.rest_framework import DjangoFilterBackend
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 配置第三方过滤类
    filter_backends = [DjangoFilterBackend] # 局部配置
    filterset_fields=['name','price']  # http://127.0.0.1:8000/books/?name=红楼梦&price=12 名字是红楼梦并且价格为12的

5.django-filter在查询中不支持模糊查询,所以如果需要模糊查询,需要自定义过滤类。

第四种:自定义过滤类

自定义过滤类需要继承:BaseFilterBackend,重写filter_queryset()方法,在这个方法里面通过queryset设置过滤规则。最后返回queryset。

from rest_framework.filters import BaseFilterBackend

class MyFilterByPrice(BaseFilterBackend):
    # 支持http://127.0.0.1:8000/books/?price_gt=12
    def filter_queryset(self, request, queryset, view):
        # queryset就是要过滤的数据
        price = request.query_params.get('price_gt')
        if price:
        # 这里可以设置模糊查询
            queryset = queryset.filter(price__gt=price)

        return queryset  # 把过滤完的数据返回

版权声明:本文为qingyanhuan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。