Django restframework 分页

如Django内置的paginator一样,restframework也封装好了分页。且有两种分类方法,一种是将普通的分页,另一种页则是针对下拉后加载更多内容的分页方式。

serializer不需要更改:

class PageArticleSerializer(serializers.ModelSerializer):
    #category = serializers.CharField(source='category.name')
    #tag = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = "__all__"

    #def get_tag(self, obj):
        #return obj.tag.values('id', 'title')

views.py

方式一:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination

from api.models import *
from api.serializer import *

class PageArticleView(APIView):
    def get(self, request, *args, **kwargs):
        queryset = Article.objects.all()
        page_object = PageNumberPagination() # 实例化PageNumberPagination()对象
        result = page_object.paginate_queryset(queryset, request, self) # 进行分页,request用来从url中获取页码
        ser = PageArticleSerializer(instance=result, many=True) # 系列化
        return page_object.get_paginated_response(ser.data)

返回的结果:

{
    "count": 4,
    "next": "http://127.0.0.1:8000/page/article/?page=2",
    "previous": null,
    "results": [
        {
            "id": 1,
            "status": 1,
            "title": "标题1",
            "summary": "这是第1篇",
            "content": "dafsdsfdsaf这是第11篇",
            "category": 2,
            "tag": [
                1,
                2
            ]
        },
        {
            "id": 2,
            "status": 1,
            "title": "标题2",
            "summary": "这是第二篇",
            "content": "dafsdsfdsaf这是第二篇",
            "category": 1,
            "tag": []
        }
    ]
}

可以看到,它还做了进一步处理,count为总的对象数量,next 即下一页的地址,previous则是上页的地址

如果只需要查询数据则将views写成这样:

class PageArticleView(APIView):
    def get(self, request, *args, **kwargs):
        queryset = Article.objects.all()
        page_object = PageNumberPagination()

        result = page_object.paginate_queryset(queryset, request, self)
        ser = PageArticleSerializer(instance=result, many=True)
        return Response(ser.data)

结果 :

[
    {
        "id": 1,
        "status": 1,
        "title": "标题1",
        "summary": "这是第1篇",
        "content": "dafsdsfdsaf这是第11篇",
        "category": 2,
        "tag": [
            1,
            2
        ]
    },
    {
        "id": 2,
        "status": 1,
        "title": "标题2",
        "summary": "这是第二篇",
        "content": "dafsdsfdsaf这是第二篇",
        "category": 1,
        "tag": []
    }
]

第三种,定制显示哪些字段:比如我不想显示 下一页的链接,只需要总数量

class PageArticleView(APIView):
    def get(self, request, *args, **kwargs):
        queryset = Article.objects.all()
        page_object = PageNumberPagination()
        result = page_object.paginate_queryset(queryset, request, self)
        ser = PageArticleSerializer(instance=result, many=True)

        return Response({'count':page_object.page.paginator.count, 'result':ser.data})

结果:

{
    "count": 4,
    "result": [
        {
            "id": 1,
            "status": 1,
            "title": "标题1",
            "summary": "这是第1篇",
            "content": "dafsdsfdsaf这是第11篇",
            "category": 2,
            "tag": [
                1,
                2
            ]
        },
        {
            "id": 2,
            "status": 1,
            "title": "标题2",
            "summary": "这是第二篇",
            "content": "dafsdsfdsaf这是第二篇",
            "category": 1,
            "tag": []
        }
    ]
}

LimitOffsetPagination 的写法待更新

update:

使用LimitOffsetPagination

views.py

from rest_framework.pagination import LimitOffsetPagination

class LimitedPageArticleView(APIView):
    def get(self, request, *args, **kwargs):
        queryset = Article.objects.all()
        page_object = LimitOffsetPagination()
        result = page_object.paginate_queryset(queryset, request, self)
        ser = PageArticleSerializer(instance=result, many=True)
        return Response(ser.data)

url:

url(r'^article/page/$', LimitedPageArticleView.as_view(), name='limit_page_article'),

请求路径:

127.0.0.1:8000/article/page/?offset=0&limit=3

这里的offset指从哪里开始,limit限制取多少条

结果 :

[
    {
        "id": 1,
        "status": 1,
        "title": "标题1",
        "summary": "这是第1篇",
        "content": "dafsdsfdsaf这是第11篇",
        "category": 2,
        "tag": [
            1,
            2
        ]
    },
    {
        "id": 2,
        "status": 1,
        "title": "标题2",
        "summary": "这是第二篇",
        "content": "dafsdsfdsaf这是第二篇",
        "category": 1,
        "tag": []
    },
    {
        "id": 3,
        "status": 1,
        "title": "article1",
        "summary": "fdsdaf",
        "content": "idasfaf",
        "category": 2,
        "tag": []
    }
]

这种情况存在一种问题,如果用户故意表示过大的数量,会导致问题,此时就需要限制max_limit ,可以在settings中,也可以自定义一个类,

class HulaLimitOffsetPagination(LimitOffsetPagination):
    max_limit = 2

page_object = HulaLimitOffsetPagination()

 

上一篇:Django restframework 初识

下一篇:Django restframework 视图