七、Django rest framework 过滤排序分页

一、过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

pip install django-filter
在配置文件中增加过滤后端的设置:

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

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

在视图中添加filter_fields属性,指定可以过滤的字段

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_fields = ('btitle', 'bread')

# 127.0.0.1:8000/books/?btitle=西游记

然后访问127.0.0.1:8000/books/?btitle=西游记
在这里插入图片描述

二、排序

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

  • 在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

  • 前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

示例:

from rest_framework.filters import OrderingFilter

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    #指定过滤后端为排序
    filter_backends = [OrderingFilter]
    #指定排序字段
    ordering_fields = ('id', 'bread', 'bpub_date')

# http://127.0.0.1:8000/books/?ordering=-id

访问http://127.0.0.1:8000/books/?ordering=-id,以id从大到小排序
在这里插入图片描述

三、分页Pagination

REST framework提供了分页的支持。

1、我们可以在配置文件中设置全局的分页方式

如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 2  # 每页数目
}

设置了上面两行后访问/books,可以看到返回的数据格式也发生了改变,count为总数量,results里为分页后返回的数据,这里只有两个数据

在这里插入图片描述
注意:全局的方式不支持指定每页个数,所以还需要下面的自定义分页器

2、也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。

from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
    page_size = 2
    page_size_query_param = 'page_size'
    max_page_size = 100

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

可选分页器

1) PageNumberPagination

前端访问网址形式:

GET  http://api.example.org/books/?page=4&page_size=2

可以在子类中定义的属性:

page_size 每页数目
page_query_param 前端发送的页数关键字名,默认为"page"
page_size_query_param 前端发送的每页数目关键字名,默认为None
max_page_size 前端最多能设置的每页数量
from rest_framework.pagination import PageNumberPagination

class StandardPageNumberPagination(PageNumberPagination):
    page_size = 2
    page_query_param = 'page'
    page_size_query_param = 'page_size'
    max_page_size = 10

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all().order_by('id')
    serializer_class = BookInfoSerializer
    #指定自定义分页器
    pagination_class = StandardPageNumberPagination
    
# 127.0.0.1/books/?page=2&page_size=2

访问第二页,每页格式为2 http://127.0.0.1:8000/books/?page=2&page_size=2
在这里插入图片描述

2)LimitOffsetPagination

前端访问网址形式:

GET http://api.example.org/books/?limit=100&offset=400

可以在子类中定义的属性:

default_limit 默认限制,默认值与PAGE_SIZE设置一直
limit_query_param limit参数名,默认'limit'
offset_query_param offset参数名,默认'offset'
max_limit 最大limit限制,默认None
from rest_framework.pagination import LimitOffsetPagination

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all().order_by('id')
    serializer_class = BookInfoSerializer
    pagination_class = LimitOffsetPagination

# 127.0.0.1:8000/books/?offset=3&limit=2

3、在自定义APIView的get方法中使用分页器

参考 rest_framework 分页器组件
上面的示例中直接指定pagination_class来使用分页器,因为drf帮我们把get视图方法已经写好了,我们只需要指定分页器。但如果有时候drf的方法不能满足我们的需求,我们需要自己来定义视图方法的时候,就需要自己调用分页器了。
示例

class BookListAPIView(APIView):
    """列表视图"""

    def get(self, request):
        """查询所有"""
        queryset = BookInfo.objects.all()
        pagePagination = PageNumberPagination()   # 产生一个分页器对象
        pagePagination.page_query_param = 'page'  # 前台查询第几页的参数,一般不需要改,系统默认查询参数为 page
        pagePagination.page_size_query_param='page_size' #前端发送的每页数目关键字名,默认为None
        pagePagination.max_page_size = 100  # 后台控制显示的最大记录条数,防止前台输入的查询条数过大
        ret = pagePagination.paginate_queryset(queryset, request)  # 必须传两个参数,第一个queryset对象要分页的所有数量,第二个参数request
        serializer = BookInfoModelSerializer(instance=ret, many=True)
        return Response(serializer.data)

可以使用自定义分页器,将一些参数在自定义分页器中设置好,省得每次都有重复设置。

class StandardPageNumberPagination(PageNumberPagination):
    page_size = 2
    page_query_param = 'page'
    page_size_query_param = 'page_size'
    max_page_size = 100

class BookListAPIView(APIView):
    """列表视图"""

    def get(self, request):
        """查询所有"""
        qs = BookInfo.objects.all()

        pagePagination = StandardPageNumberPagination()   # 产生一个自定义分页器对象,下面注释部分在自定义分页器中已经设置了
        #pagePagination.page_query_param = 'page'  # 前台查询第几页的参数,一般不需要改,系统默认查询参数为 page
        #pagePagination.page_size_query_param='page_size' #前端发送的每页数目关键字名,默认为None
        #pagePagination.max_page_size = 100  # 后台控制显示的最大记录条数,防止前台输入的查询条数过大

        pagedata = pagePagination.paginate_queryset(qs, request)  # 必须传两个参数,第一个queryset对象要分页的所有数量,第二个参数request

        serializer = BookInfoModelSerializer(instance=pagedata, many=True)  #对数据进行序列化
        
        pageresponse = pagePagination.get_paginated_response(serializer.data)  # 将序列化后的数据再转为分页格式的输出,有带count等参数,如果没有这一步,则还是默认的输出方式

        return Response(pageresponse.data)

路由

re_path(r'^books/$', views.BookListAPIView.as_view())

访问正常http://127.0.0.1:8000/books/?page=2&page_size=3
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值