过滤器(条件查询 排序 ) 分页器

Posted xp1315458571

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤器(条件查询 排序 ) 分页器相关的知识,希望对你有一定的参考价值。

一、群查接口各种筛选组件

数据准备

技术图片

 

 

models.py
技术图片
class Car(models.Model):
    name = models.CharField(max_length=16, unique=True, verbose_name=车名)
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=价格)
    brand = models.CharField(max_length=16, verbose_name=品牌)
?
    class Meta:
        db_table = api_car
        verbose_name = 汽车表
        verbose_name_plural = verbose_name
?
    def __str__(self):
        return self.name
View Code
admin.py   注册
admin.site.register(models.Car)
serializers.py
class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Car
        fields = [name, price, brand]
views.py
# Car的群查接口
from rest_framework.generics import ListAPIView
?
class CarListAPIView(ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
urls.py
url(r^cars/$, views.CarListAPIView.as_view()),

1.drf  搜索 过滤组件

views.py
from rest_framework.generics import ListAPIView
?
# 第一步:drf的SearchFilter - 搜索过滤
from rest_framework.filters import SearchFilter
?
class CarListAPIView(ListAPIView):
    queryset = models.Car.objects  # 固定的两个东西,源码内部默认为Noen
    serializer_class = serializers.CarModelSerializer
?
    # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [SearchFilter]
?
    # 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
    search_fields = [name, price]
    # eg:/cars/?search=1,name和price中包含1的数据都会被查询出

2. drf  排序  过滤组件

views.py
from rest_framework.generics import ListAPIView
?
# 第一步:drf的OrderingFilter - 排序过滤
from rest_framework.filters import OrderingFilter
?
class CarListAPIView(ListAPIView):
    queryset = models.Car.objects
    serializer_class = serializers.CarModelSerializer
?
    # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [OrderingFilter]
?
    # 第三步:OrderingFilter过滤类依赖的过滤条件 => 接口:/cars/?ordering=...
    ordering_fields = [pk, price]
    # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序

3. drf  基础分页组件

api / pahenations.py
from rest_framework.pagination import PageNumberPagination
?
class MyPageNumberPagination(PageNumberPagination):
    # ?page=1,这个就是url中的key,
    page_query_param = page
# ?page=1 不传自定义条数时默认一页显示的条数,可以通过下面的参数设置自定义 page_size = 3 # ?page=2&page_size=3 第二页每页显示3条数据 用户自定义一页显示的条数 page_size_query_param = page_size
# 用户自定义一页显示的条数最大限制:数值超过5也只显示5条 max_page_size = 5
views.py
from rest_framework.generics import ListAPIView
?
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题,上面搜索和排序不需要all是因为人家已经过滤过了
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyPageNumberPagination

技术图片

4. drf 偏移分页组件

pahenations.py
from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
    # ?offset=从头偏移的条数&limit=要显示的条数
    limit_query_param = limit
    offset_query_param = offset
    # ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
    default_limit = 3
    # ?limit可以自定义一页显示的最大条数
    max_limit = 5
?
    # 在偏移组件基础上只使用limit结合ordering可以实现排行前几或后几,后面我们会自定义limit过滤器就不需要基于分页了
    # ?ordering=-price&limit=2  => 价格前2
views.py
from rest_framework.generics import ListAPIView
?
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyLimitOffsetPagination

5. drf游标分页组件(了解)

pahenations.py
# 注:必须基于排序规则下进行分页
# 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering
# 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
    cursor_query_param = cursor
    page_size = 3
    page_size_query_param = page_size
    max_page_size = 5
    ordering = -pk  # 按照pk降序排列
views.py
from rest_framework.generics import ListAPIView
?
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyCursorPagination

6. 自定义 limit 过滤器

我不想借助分页,我就想自定义一个条数过滤器,他可以对各过滤组件过滤结果进行显示限制

filters.py
# 自定义过滤器,接口:?limit=显示的条数
class LimitFilter:
    def filter_queryset(self, request, queryset, view):
        # 前台固定用 ?limit=... 传递过滤参数
        limit = request.query_params.get(limit)
        if limit:
            limit = int(limit)
            return queryset[:limit]  # 切片,限制条数
        return queryset
    # eg:/cars/?ordering=-price,pk&limit=3,先按price降序,如果出现price相同,再按pk升序,筛选结果显示3条
views.py
from rest_framework.generics import ListAPIView
?
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [LimitFilter]

7. 过滤器插件:django-filter

安装
>: pip3 install django-filter
过滤条件层:自定义api/filters.py
# django-filter插件过滤器类
from django_filters.rest_framework.filterset import FilterSet
from . import models
?
# 自定义过滤字段
from django_filters import filters
class CarFilterSet(FilterSet): min_price = filters.NumberFilter(field_name=price, lookup_expr=gte) # gte lte 源码里面有,表示最大最小值 max_price = filters.NumberFilter(field_name=price, lookup_expr=lte) class Meta: model = models.Car fields = [brand, min_price, max_price] # brand是model中存在的字段,一般都是可以用于分组的字段 # min_price、max_price是自定义字段,需要自己自定义过滤条件
视图层:views.py
# django-filter插件过滤器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet
?
class CarListAPIView(ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [DjangoFilterBackend]
    
    # django-filter过滤器插件使用
    filter_class = CarFilterSet
    # 接口:?brand=...&min_price=...&max_price=...
    # eg:?brand=宝马&min_price=5&max_price=10 => 5~10间的宝马牌汽车

 


   
   

 

 

以上是关于过滤器(条件查询 排序 ) 分页器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Twig 中为 KNP 分页器获取分页方向?

排序在 Knp 分页器中不起作用

动态数据的分页器/排序不起作用

Tablesorter - 排序时可以自动禁用分页器吗?

通过模型关系列对分页器对象进行排序

drf 其他功能组件 - 限流-过滤-排序-分页-异常处理-生成接口文档-Xadmin