drf之过滤与排序

发布时间 2023-04-26 20:23:47作者: 树苗叶子

过滤类

内置过滤类

内置过滤类必须继承GenericAPIView及其子类
内置过滤类为模糊搜索,只要包含查询条件中的内容即可
只能传入一个参数

使用方法

# 导入模块
from rest_framework.filters import SearchFilter
# 在视图类中注册过滤功能
filter_backends = [SearchFilter]
# 指定过滤的字段,如果指定多个字段,则是或的条件
search_fields = ['字段名']
# 使用时,在查询条件最后使用search关键字进行过滤

示例

from app01 import models
from app01.serializer.serializer import BookModelSerializer
from rest_framework.viewsets import ViewSet, ViewSetMixin
from rest_framework.generics import RetrieveAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.filters import SearchFilter


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # 注册内置过滤功能
    filter_backends = [SearchFilter]
    # 指定按哪个字段过滤,如果指定多个字段,则是或的关系,查询条件只有一个search,所以就是search=xxx就是不管name还是price只要有xxx就可以匹配到
    search_fields = ['name', 'price']

查询方式:
http://127.0.0.1:8000/api/v1/book/?search=380
image

第三方过滤类

  1. 安装第三方模块 django-filter

使用第三方自带过滤方法

  1. 导入模块 from django_filters.rest_framework import DjangoFilterBackend
  2. 在视图类中使用
    • 注册第三方过滤功能:filter_backends = [DjangoFilterBackend]
    • 配置过滤项,可以配置多项,配置什么,搜索条件就是什么,并且多个搜索条件之间是and关系:filterset_fields = ['字段1', '字段2']

示例

from app01 import models
from app01.serializer.serializer import BookModelSerializer
from rest_framework.viewsets import ViewSetMixin
from rest_framework.generics import ListAPIView
from django_filters.rest_framework import DjangoFilterBackend


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # 注册第三方过滤功能
    filter_backends = [DjangoFilterBackend]  # 这里可以配置多个过滤条件,从左向右匹配
    # 配置过滤项,可以配置多项,配置什么,搜索条件就是什么,并且多个搜索条件之间是and关系
    filterset_fields = ['name', 'price']

第三方过滤方法之自定义

  • 比如查询价格大于370的商品
  1. 新建py文件,自定义过滤类,重写filter_queryset(self, request, queryset, view)方法
  2. 在方法内定义过滤条件
  3. 在视图类中引用filter_backends = [自定义过滤类]

示例

filter.py(自己创建,随意命名)

from django_filters.rest_framework import DjangoFilterBackend


class CustFilter(DjangoFilterBackend):
    def filter_queryset(self, request, queryset, view):
        price_gt = request.GET.get('price_gt', None)
        # 如果有过滤条件,则按过滤条件返回,如果没有过滤条件,则返回所有数据
        if price_gt:
            return queryset.filter(price__gt=int(price_gt))
        else:
            return queryset

views.py

from app01 import models
from app01.serializer.serializer import BookModelSerializer
from rest_framework.viewsets import ViewSet, ViewSetMixin
from rest_framework.generics import RetrieveAPIView, ListAPIView
from rest_framework.response import Response
from app01.filter import CustFilter


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # 注册第三方过滤功能
    filter_backends = [CustFilter]

搜索条件为:http://127.0.0.1:8000/api/v1/book/?price_gt=380

排序

使用方法

  1. 导入内置模块
    • from rest_framework.filters import OrderingFilter
  2. 在视图类中注册配置
    • filter_backends = [OrderingFilter]
    • ordering_fields = ['排序列1', '排序列2']
  3. 查询条件ordering=排序列1,排序列2...

示例

from rest_framework.filters import OrderingFilter


class BookView(ViewSetMixin, ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # 注册第三方过滤功能
    filter_backends = [OrderingFilter]
    ordering_fields = ['id', 'price']

查询方法:
正序:http://127.0.0.1:8000/api/v1/book/?ordering=price
倒序:http://127.0.0.1:8000/api/v1/book/?ordering=-price 只需要在查询条件加个负号
多个条件排序:http://127.0.0.1:8000/api/v1/book/?ordering=price,id