如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()