DRF排序与过滤

排序

排序功能接口只针对于:获取所有数据,也就是list方法接口,并且视图类需要继承GenericAPIView及其子类。

DRF中排序类使用起来非常简单,只需要去视图类中把视图类加进去。

视图类:

from rest_framework.generics import ListAPIView
from rest_framework.filters import OrderingFilter
from .models import Book
from .serializer import BookSerializer

class BookView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 重写GenericAPIView提供的属性,把排序类加进去
    filter_backends = [OrderingFilter, ]
    # 需要排序的字段,不写默认为序列化类所有字段
    ordering_fields = ['price']
    
    def get(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

根据访问地址中带参数来排序

查询所有的接口:

http://127.0.0.1:8000/books

按price字段升序排序:

http://127.0.0.1:8000/books?ordering=price

降序排序:

http://127.0.0.1:8000/books?ordering=-price

多字段排序:

http://127.0.0.1:8000/books?ordering=字段1,字段2

过滤

过滤用于筛选数据,与排序一样,只作用于调用了list方法的接口,并且视图类要继承GenericAPIView类及其子类。

内置过滤类

SearchFilter过滤类

SearchFilter用于模糊查询。

视图类:

from rest_framework.generics import ListAPIView
from rest_framework.filters import SearchFilter
from .models import Book
from .serializer import BookSerializer

class BookView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 重写GenericAPIView提供的属性,把过滤类加进去
    filter_backends = [SearchFilter, ]
    # 需要过滤的字段,不写就无法过滤
    search_fields = ['name', 'price']

    def get(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

根据访问地址中带参数来过滤

查询所有的接口:

http://127.0.0.1:8000/books

过滤:

http://127.0.0.1:8000/books?search=5

根据search_fields过滤数据,search=5相当于:

name like 5 or price like 5

第三方过滤类

安装:

pip install django-filter

视图类使用:

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import ListAPIView
from .models import Book
from .serializer import BookSerializer

class BookView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 重写GenericAPIView提供的属性,把过滤类加进去
    filter_backends = [DjangoFilterBackend, ]
    # 需要过滤的字段
    filter_fields = ['name', 'price']

    def get(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

根据访问地址中带参数来过滤

过滤:

http://127.0.0.1:8000/books?name=xx&peice=5

相当于:

name=xx and price=5

自定义过滤类

自定义过滤类

from rest_framework.filters import BaseFilterBackend
# 继承BaseFilterBackend
class BookFilter(BaseFilterBackend):
    # 重写filter_queryset
    def filter_queryset(self, request, queryset, view):
        """主要操作queryset参数"""
        # 返回的数据就是过滤后的数据
        return queryset.filter(price__gt=50)

视图类使用:

from rest_framework.generics import ListAPIView
from .models import Book
from .serializer import BookSerializer
# 导入过滤类
from .throttling import BookFilter
class BookView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 重写GenericAPIView提供的属性,把过滤类加进去
    filter_backends = [BookFilter, ]

    def get(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

不需要额外参数,直接发送get请求即可。

排序过滤原理

关键在于GenericAPIView类中的filter_queryset方法

image

posted @ 2022-06-21 17:25  Yume_Minami  阅读(87)  评论(0编辑  收藏  举报