简言
-
排序和过滤只针对查询所有
【一】排序
from rest_framework.filters import OrderingFilter class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommentThrottle] # 排序 filter_backends = [OrderingFilter] # 可以按照一个字段,也可以多个字段 # http://127.0.0.1:8000/api/v1/books/?ordering=price # 升序 # http://127.0.0.1:8000/api/v1/books/?ordering=-price # 降序 # http://127.0.0.1:8000/api/v1/books/?ordering=price,-id # 两个字段 ordering_fields = ['price', 'id'] queryset = Book.objects.all() serializer_class = BookSerializer
【二】过滤
# 方法一:drf内置的,只能用search模糊匹配 from rest_framework.filters import SearchFilter class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommentThrottle] filter_backends = [OrderingFilter, SearchFilter] # 过滤和排序可以一起使用 ordering_fields = ['price', 'id'] # 名字中有“红”的都能搜出来 search_fields = ['name'] queryset = Book.objects.all() serializer_class = BookSerializer
# 方法二:使用第三方插件 django-filter # 安装 pip3 install django-filter from django_filters.rest_framework.backends import DjangoFilterBackend class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommentThrottle] filter_backends = [OrderingFilter, DjangoFilterBackend] ordering_fields = ['price', 'id'] # http://127.0.0.1:8000/api/v1/books/?price=20&name=红楼梦 # 指定匹配搜索的书名 search_fields = ['name '] queryset = Book.objects.all() serializer_class = BookSerializer
# 方法三:自定义类 # 创建一个filter.py文件 from rest_framework.filters import BaseFilterBackend from django.db.models import Q class CommonFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): # 名字中带红的,价格 大于 xx 价格小于 xx # ?name=红&price_gt=10&price_lt=100 name = request.query_params.get('name') price_gt = request.query_params.get('price_gt') price_lt = request.query_params.get('price_lt') if name and price_gt and price_lt: # 精准匹配 # queryset = queryset.filter(Q(name=name) | Q(price=price)) # 模糊匹配 queryset = queryset.filter(Q(name__contains=name) | Q(price__gt=price_gt) | Q(price__lt=price_lt)) elif name and price_gt: # queryset = queryset.filter(name=name) queryset = queryset.filter(Q(name__contains=name) | Q(price__gt=price_gt)) elif name and price_lt: queryset = queryset.filter(Q(name__contains=name) | Q(price__lt=price_lt)) elif name: queryset = queryset.filter(name__contains=name) elif price_gt: queryset = queryset.filter(price__lt=price_lt) elif price_lt: queryset = queryset.filter(price__gt=price_gt) return queryset
-
views.py
from .filters import CommonFilter class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommonThrottle] filter_backends = [OrderingFilter, CommonFilter] ordering_fields = ['price', 'id'] queryset = Book.objects.all() serializer_class = BookSerializer
【三】分页
# 1 分页只针对于查询所有 -如果是app---》下拉加载下一页 -web端---》点击下一页 # 2 drf帮咱们提供了三种分页方式 # 3 使用步骤: 1 定义一个类,继承三个分页类之一 2 在分页类中,重写某些类属性 3 在继承GenericAPIView的子类中,配置 pagination_class = CommonCursorPagination
# 方法一:基本分页 # pagination from rest_framework.pagination import LimitOffsetPagination, CursorPagination, PageNumberPagination # http://api.example.org/accounts/?page=4 # http://api.example.org/accounts/?page=4&size=10 class CommonPageNumberPagination(PageNumberPagination): # 默认一页显示两条 page_size = 2 # 查询条件 page_query_param = 'page' # 每页显示多少条的查询条件 size=10 page_size_query_param = 'size' # 虽然可以指定每页显示多少条,但是最多显示5条 max_page_size = 5 # views.py from .pagination import CommonPageNumberPagination class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommonThrottle] filter_backends = [OrderingFilter, CommonFilter] ordering_fields = ['price', 'id'] pagination_class = CommonPageNumberPagination queryset = Book.objects.all() serializer_class = BookSerializer
# 方法二:偏移分页 from rest_framework.pagination import LimitOffsetPagination, CursorPagination, PageNumberPagination class CommonLimitOffsetPagination(LimitOffsetPagination): # http://127.0.0.1:8000/api/v1/books/?limit=3 # http://127.0.0.1:8000/api/v1/books/?offset=0&limit=3 # 默认条数 default_limit =2 # limit的查询提交,显示多少条 limit_query_param = 'limit' # 偏移量 -- 》从第一条开始,偏移位置 offset_query_param = 'offset' # 最大显示条数 max_limit = 5 # views.py from .pagination import CommonLimitOffsetPagination class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommonThrottle] filter_backends = [OrderingFilter, CommonFilter] ordering_fields = ['price', 'id'] pagination_class = CommonLimitOffsetPagination queryset = Book.objects.all() serializer_class = BookSerializer
# 方法三:游标分页 只能上一页或下一页跳转 效率高,但是大数据量分页快 # 必须根据上一页的返回,才能知道下一页地址是什么 # http://127.0.0.1:8000/api/v1/books/ class CommonCursorPagination(CursorPagination): # 查询条件 cursor_query_param = 'cursor' # 每页显示 2 条 page_size = 2 # 按某个字段排序--》这个字段必须是表中的字段 ordering = 'id' # views.py from .pagination import CommonCursorPagination class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ): authentication_classes = [LoginAuth] permission_classes = [CommonPermission] throttle_classes = [CommonThrottle] filter_backends = [OrderingFilter, CommonFilter] ordering_fields = ['price', 'id'] pagination_class = CommonCursorPagination queryset = Book.objects.all() serializer_class = BookSerializer