Django Rest Framework源码剖析(七)-----分页

<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0"><tr>
<td><span style="font-size: 16px;">一、简介</td>
</tr></table>

分页对于大多数网站来说是必不可少的,那你使用restful架构时候,你可以从后台获取数据,在前端利用利用框架或自定义分页,这是一种解决方案。当然django rest framework提供了分页组件,让我们可以更灵活的进行分页。

django rest framework提供了三种分页组件:

  • PageNumberPagination:普通分页,查看第n页,每个页面显示n条数据
  • LimitOffsetPagination: 基于位置的分页,在第n个位置,向后查看n条数据,和数据库的sql语句中的limit offset类似,参数offet代表位置,limit代表取多少条数据。
  • CursorPagination:游标分页,意思就是每次返回当前页、上一页、下一页,并且每次的上一页和下一页的url是不规则的

<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0"><tr>
<td><span style="font-size: 16px;">二、每个分页组件使用</td>
</tr></table>

这里我们使用之前的模型,如果没有在setting中注册django rest framework 请注册它,为了方便我们查看分页,配置项在INSTALLED_APPS:

1.PageNumberPagination类分页

settings.py

INSTALLED_APPS =, ]

models.py

django.db <span style="color: #0000ff;">class<span style="color: #000000;"> UserInfo(models.Model):
user_type_choice
=<span style="color: #000000;"> (
(1,<span style="color: #800000;">"<span style="color: #800000;">普通用户<span style="color: #800000;">"<span style="color: #000000;">),(2,<span style="color: #800000;">"<span style="color: #800000;">会员<span style="color: #800000;">"<span style="color: #000000;">),)
user_type = models.IntegerField(choices=<span style="color: #000000;">user_type_choice)
username = models.CharField(max_length=32,unique=<span style="color: #000000;">True)
password = models.CharField(max_length=64<span style="color: #000000;">)
group = models.ForeignKey(to=<span style="color: #800000;">'<span style="color: #800000;">UserGroup<span style="color: #800000;">',null=True,blank=<span style="color: #000000;">True)
roles = models.ManyToManyField(to=<span style="color: #800000;">'<span style="color: #800000;">Role<span style="color: #800000;">'<span style="color: #000000;">)

<span style="color: #0000ff;">class<span style="color: #000000;"> UserToken(models.Model):
user = models.OneToOneField(to=<span style="color: #000000;">UserInfo)
token = models.CharField(max_length=64<span style="color: #000000;">)

<span style="color: #0000ff;">class<span style="color: #000000;"> UserGroup(models.Model):
<span style="color: #800000;">"""<span style="color: #800000;">用户组<span style="color: #800000;">"""<span style="color: #000000;">
name = models.CharField(max_length=32,unique=<span style="color: #000000;">True)

<span style="color: #0000ff;">class<span style="color: #000000;"> Role(models.Model):
<span style="color: #800000;">"""<span style="color: #800000;">角色<span style="color: #800000;">"""<span style="color: #000000;">
name = models.CharField(max_length=32,unique=True)

urls.py

urlpatterns =</span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; url(r'^api/v1/auth',views.AuthView.as_view()),</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; url(r'^api/v1/order',views.OrderView.as_view()),</span> url(r<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;^api/v1/roles</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,views.RoleView.as_view()),<span style="color: #ff6600;"&gt;#分页示例1</span> url(r</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;^api/v1/userinfo</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,views.UserinfoView.as_view()),url(r</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;^api/v1/group/(?P<xxx>\d+)</span><span style="color: #800000;"&gt;'</span>,views.GroupView.as_view(),name=<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;gp</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;),</span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; url(r'^api/(?P<version>[v1|v2]+)/user',views.UserView.as_view(),name="user_view"),</span>

]

本次我们使用roles来作为示例,并且为了更好的显示,此次会用到django rest framework 的响应(Response),后续会介绍,下面是对角色视图的序列化,这个已经在前面的序列化篇章中说明如下:

rest_framework rest_framework.response Response RolesSerializer(serializers.Serializer): id=serializers.IntegerField() name= get(self,request,*args,**==RolesSerializer(instance=roles,many=True) Response(res.data)

访问:http://127.0.0.1:8000/api/v1/roles,显示出所有的角色,如下:

加入分页后的角色视图:

rest_framework rest_framework.response Response rest_framework.pagination RolesSerializer(serializers.Serializer): id=serializers.IntegerField() =models.Role.objects.all() =PageNumberPagination() pg_res=pg_obj.paginate_queryset(queryset=roles,request=request,view= res=RolesSerializer(instance=pg_res,many=True) Response(res.data)

同时,我们还需要配置每页显示的数据条数,在settings.py中:

REST_FRAMEWORK =: [,], :2, }

此时我们访问:http://127.0.0.1:8000/api/v1/roles?page=1,则显示第一页,访问http://127.0.0.1:8000/api/v1/roles?page=2则显示第二页,如下图:

但是一般情况我们需要自己定义分页类,来定制更多的功能,示例:

自定义分页,更多的定制功能:

rest_framework rest_framework.response Response rest_framework.pagination <span style="color: #0000ff;">class<span style="color: #000000;"> Mypagination(PageNumberPagination):
<span style="color: #800000;">"""
<span style="color: #800000;">自定义分页
<span style="color: #800000;">"""
<span style="color: #000000;">
page_size
=2 <span style="color: #008000;">#
<span style="color: #008000;">默认每页显示个数配置

page_query_param = <span style="color: #800000;">'
<span style="color: #800000;">p<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 页面传参的key,默认是page
page_size_query_param=<span style="color: #800000;">'<span style="color: #800000;">size<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 指定每页显示个数参数
max_page_size=4 <span style="color: #008000;">#<span style="color: #008000;"> 每页最多显示个数配置,使用以上配置,可以支持每页可显示2~4条数据

<span style="color: #0000ff;">class RolesSerializer(serializers.Serializer): <span style="color: #008000;">#<span style="color: #008000;">定义序列化类
id=serializers.IntegerField() <span style="color: #008000;">#<span style="color: #008000;">定义需要提取的序列化字段,**<span style="color: #000000;">kwargs):
roles=models.Role.objects.all() <span style="color: #008000;">#<span style="color: #008000;"> 获取所有数据
<span style="color: #000000;">
pg_obj=Mypagination() <span style="color: #008000;">#<span style="color: #008000;"> 实例化分页类
pg_res=pg_obj.paginate_queryset(queryset=roles,many=True) <span style="color: #008000;">#<span style="color: #008000;"> 对分完页码的数据进行序列化
<span style="color: #0000ff;">return Response(res.data)

访问:http://127.0.0.1:8000/api/v1/roles?p=1&size=3,需要注意的是此时的分页参数已经重写,查看结果:

自带返回上一页下一页功能:

rest_framework rest_framework.response Response rest_framework.pagination <span style="color: #0000ff;">class<span style="color: #000000;"> Mypagination(PageNumberPagination):
<span style="color: #800000;">"""
<span style="color: #800000;">自定义分页
<span style="color: #800000;">"""
<span style="color: #000000;">
page_size
=2 <span style="color: #008000;">#
<span style="color: #008000;">默认每页显示个数配置

page_query_param = <span style="color: #800000;">'
<span style="color: #800000;">p<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 页面传参的key,many=True) <span style="color: #008000;">#<span style="color: #008000;"> 对分完页码的数据进行序列化
<span style="color: #0000ff;">return pg_obj.get_paginated_response(res.data) <span style="color: #ff6600;"># 使用分页自带的respose返回,具有上一页下一页功能

2.LimitOffsetPagination类分页

同样我们以角色视图做示例,通过自定义实现分页,示例:

rest_framework rest_framework.response Response rest_framework.pagination <span style="color: #0000ff;">class<span style="color: #000000;"> MyLimitOffsetPagination(LimitOffsetPagination):

default_limit </span>= 2 <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt;默认显示的个数</span>
offset_query_param = <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;offset</span><span style="color: #800000;"&gt;"</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt;指定url中位置key值,其位置从0开始</span>
limit_query_param = <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;limit</span><span style="color: #800000;"&gt;"</span>  <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 指定url中的偏移个数(显示个数)的key值</span>
max_limit = 10  <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt;最多显示(偏移)的个数</span>

<span style="color: #0000ff;">class RolesSerializer(serializers.Serializer): <span style="color: #008000;">#<span style="color: #008000;">定义序列化类
id=serializers.IntegerField() <span style="color: #008000;">#<span style="color: #008000;">定义需要提取的序列化字段,**<span style="color: #000000;">kwargs):
roles=models.Role.objects.all() <span style="color: #008000;">#<span style="color: #008000;"> 获取所有数据
<span style="color: #000000;">
pg_obj=MyLimitOffsetPagination() <span style="color: #008000;">#<span style="color: #008000;"> 实例化分页类
pg_res=pg_obj.paginate_queryset(queryset=roles,many=True) <span style="color: #008000;">#<span style="color: #008000;"> 对分完页码的数据进行序列化
<span style="color: #0000ff;">return Response(res.data)

访问:http://127.0.0.1:8000/api/v1/roles?offset=1&limit=4(从第2个位置开始,查看4条数据),结果如下:

3.CursorPagination类实现分页(很少用)

示例:

rest_framework rest_framework.response Response rest_framework.pagination <span style="color: #0000ff;">class<span style="color: #000000;"> MyCursorPagination(CursorPagination):
cursor_query_param
= <span style="color: #800000;">"
<span style="color: #800000;">cursor
<span style="color: #800000;">"
<span style="color: #008000;">#
<span style="color: #008000;">url获取分页的key

page_size = 2 <span style="color: #008000;">#
<span style="color: #008000;">每页显示2个数据

ordering = <span style="color: #800000;">'<span style="color: #800000;">id<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;">排序规则
page_size_query_param = <span style="color: #800000;">'<span style="color: #800000;">size<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;">每页显示多少条参数配置
max_page_size = 5 <span style="color: #008000;">#<span style="color: #008000;">每页最多显示多少条数据
<span style="color: #0000ff;">class RolesSerializer(serializers.Serializer): <span style="color: #008000;">#<span style="color: #008000;">定义序列化类
id=serializers.IntegerField() <span style="color: #008000;">#<span style="color: #008000;">定义需要提取的序列化字段,**<span style="color: #000000;">kwargs):
roles=models.Role.objects.all() <span style="color: #008000;">#<span style="color: #008000;"> 获取所有数据
<span style="color: #000000;">
pg_obj=MyCursorPagination() <span style="color: #008000;">#<span style="color: #008000;"> 实例化分页类
pg_res=pg_obj.paginate_queryset(queryset=roles,many=True) <span style="color: #008000;">#<span style="color: #008000;"> 对分完页码的数据进行序列化
<span style="color: #0000ff;">return pg_obj.get_paginated_response(res.data)

访问http://127.0.0.1:8000/api/v1/roles,结果如下,从结果中可以看到下一页的url并不规则:

三、源码剖析对于以上示例,你可以会有疑问,问什么配置上了一些类的属性就能有不同的效果呢?当然源码是有这些定制配置的,这里以PageNumberPagination分页进行说明,下面是PageNumberPagination的源码,可能稍微长,我们进行配置部分解读就好,其他部分和分页相关的逻辑这里就不过多介绍,解读部分请看注释:

http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&amp;page_size=100 </span><span style="color: #800000;"&gt;"""</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; The default page size.</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Defaults to `None`,meaning pagination is disabled.</span> page_size =<span style="color: #000000;"&gt; api_settings.PAGE_SIZE <span style="color: #ff6600;"&gt;#每页显示个数配置,可以在setting中配置,也可以在类里,当前类>全局(settings)</span> django_paginator_class </span>=<span style="color: #000000;"&gt; DjangoPaginator <span style="color: #ff6600;"&gt;# 本质使用django自带的分页组件 </span></span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Client can control the page using this query parameter.</span> page_query_param = <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;page</span><span style="color: #800000;"&gt;' <span style="color: #ff6600;"&gt;# url中的页码key配置</span></span><span style="color: #000000;"&gt; page_query_description </span>= _(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;A page number within the paginated result set.</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;) <span style="color: #ff6600;"&gt; # 描述 </span></span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Client can control the page size using this query parameter.</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Default is 'None'. Set to eg 'page_size' to enable usage.</span> page_size_query_param =<span style="color: #000000;"&gt; None <span style="color: #ff6600;"&gt; # url中每页显示个数的key配置</span> page_size_query_description </span>= _(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;Number of results to return per page.</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;) </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Set to an integer to limit the maximum page size the client may request.</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Only relevant if 'page_size_query_param' has also been set.</span> max_page_size =<span style="color: #000000;"&gt; None <span style="color: #ff6600;"&gt; # 最多显示个数配置</span> last_page_strings </span>= (<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;last</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,) template </span>= <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;rest_framework/pagination/numbers.html</span><span style="color: #800000;"&gt;' <span style="color: #ff6600;"&gt;# 渲染的模板</span></span><span style="color: #000000;"&gt; invalid_page_message </span>= _(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;Invalid page.</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;) <span style="color: #ff6600;"&gt; # 页面不合法返回的信息,当然我们也可以自己定制 </span></span><span style="color: #0000ff;"&gt;def</span> paginate_queryset(self,queryset,view=<span style="color: #000000;"&gt;None): <span style="color: #ff6600;"&gt;# 获取分页数据 </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Paginate a queryset if required,either returning a page object,or `None` if pagination is not configured for this view. </span><span style="color: #800000;"&gt;"""</span><span style="color: #000000;"&gt; page_size </span>=<span style="color: #000000;"&gt; self.get_page_size(request) <span style="color: #ff6600;"&gt;# 调用get_page_size 获取当前请求的每页显示数量 </span></span><span style="color: #0000ff;"&gt;if</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; page_size: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; None paginator </span>=<span style="color: #000000;"&gt; self.django_paginator_class(queryset,page_size) page_number </span>= request.query_params.get(self.page_query_param,1<span style="color: #000000;"&gt;) </span><span style="color: #0000ff;"&gt;if</span> page_number <span style="color: #0000ff;"&gt;in</span><span style="color: #000000;"&gt; self.last_page_strings: page_number </span>=<span style="color: #000000;"&gt; paginator.num_pages </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt;: self.page </span>=<span style="color: #000000;"&gt; paginator.page(page_number) </span><span style="color: #0000ff;"&gt;except</span><span style="color: #000000;"&gt; InvalidPage as exc: msg </span>=<span style="color: #000000;"&gt; self.invalid_page_message.format( page_number</span>=page_number,message=<span style="color: #000000;"&gt;six.text_type(exc) ) </span><span style="color: #0000ff;"&gt;raise</span><span style="color: #000000;"&gt; NotFound(msg) </span><span style="color: #0000ff;"&gt;if</span> paginator.num_pages > 1 <span style="color: #0000ff;"&gt;and</span> self.template <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; None: </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; The browsable API should display pagination controls.</span> self.display_page_controls =<span style="color: #000000;"&gt; True self.request </span>=<span style="color: #000000;"&gt; request </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; list(self.page) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_paginated_response(self,data): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(OrderedDict([ (</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;count</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,self.page.paginator.count),(</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;next</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,self.get_next_link()),(</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;previous</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,self.get_previous_link()),(</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;results</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,data) ])) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_page_size(self,request): </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; self.page_size_query_param: </span><span style="color: #0000ff;"&gt;try</span><span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; _positive_int( request.query_params[self.page_size_query_param],strict</span>=<span style="color: #000000;"&gt;True,cutoff</span>=<span style="color: #000000;"&gt;self.max_page_size ) </span><span style="color: #0000ff;"&gt;except</span><span style="color: #000000;"&gt; (KeyError,ValueError): </span><span style="color: #0000ff;"&gt;pass</span> <span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; self.page_size </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_next_link(self): </span><span style="color: #0000ff;"&gt;if</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; self.page.has_next(): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; None url </span>=<span style="color: #000000;"&gt; self.request.build_absolute_uri() page_number </span>=<span style="color: #000000;"&gt; self.page.next_page_number() </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; replace_query_param(url,self.page_query_param,page_number) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_previous_link(self): </span><span style="color: #0000ff;"&gt;if</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; self.page.has_previous(): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; None url </span>=<span style="color: #000000;"&gt; self.request.build_absolute_uri() page_number </span>=<span style="color: #000000;"&gt; self.page.previous_page_number() </span><span style="color: #0000ff;"&gt;if</span> page_number == 1<span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; remove_query_param(url,self.page_query_param) </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; replace_query_param(url,page_number) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_html_context(self): base_url </span>=<span style="color: #000000;"&gt; self.request.build_absolute_uri() </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; page_number_to_url(page_number): </span><span style="color: #0000ff;"&gt;if</span> page_number == 1<span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; remove_query_param(base_url,self.page_query_param) </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; replace_query_param(base_url,page_number) current </span>=<span style="color: #000000;"&gt; self.page.number final </span>=<span style="color: #000000;"&gt; self.page.paginator.num_pages page_numbers </span>=<span style="color: #000000;"&gt; _get_displayed_page_numbers(current,final) page_links </span>=<span style="color: #000000;"&gt; _get_page_links(page_numbers,current,page_number_to_url) </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; { </span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;previous_url</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: self.get_previous_link(),</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;next_url</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: self.get_next_link(),</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;page_links</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: page_links } </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; to_html(self): template </span>=<span style="color: #000000;"&gt; loader.get_template(self.template) context </span>=<span style="color: #000000;"&gt; self.get_html_context() </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; template.render(context) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_schema_fields(self,view): </span><span style="color: #0000ff;"&gt;assert</span> coreapi <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span> None,<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;coreapi must be installed to use `get_schema_fields()`</span><span style="color: #800000;"&gt;'</span> <span style="color: #0000ff;"&gt;assert</span> coreschema <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span> None,<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;coreschema must be installed to use `get_schema_fields()`</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt; fields </span>=<span style="color: #000000;"&gt; [ coreapi.Field( name</span>=<span style="color: #000000;"&gt;self.page_query_param,required</span>=<span style="color: #000000;"&gt;False,location</span>=<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;query</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,schema</span>=<span style="color: #000000;"&gt;coreschema.Integer( title</span>=<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;Page</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,description</span>=<span style="color: #000000;"&gt;force_text(self.page_query_description) ) ) ] </span><span style="color: #0000ff;"&gt;if</span> self.page_size_query_param <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; None: fields.append( coreapi.Field( name</span>=<span style="color: #000000;"&gt;self.page_size_query_param,schema</span>=<span style="color: #000000;"&gt;coreschema.Integer( title</span>=<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;Page size</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,description</span>=<span style="color: #000000;"&gt;force_text(self.page_size_query_description) ) ) ) </span><span style="color: #0000ff;"&gt;return</span> fields</pre>
四、使用总结虽然对于分页来说,django rest framework 给我们提供了多种分页,但是最为常用的还是第一种PageNumberPagination,推荐使用。

而第二种LimitOffsetPagination,使用场景是当数据量比较大时候,只关心其中某一部分数据,推荐使用。

CursorPagination类型分页相对于PageNumberPagination有点在于,它避免了人为在url中自己传入参数进行页面的刷新(因为url不规则),缺点也显而易见只能进行上下页的翻阅。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


注:所有源代码均实测运行过。所有源代码均已上传CSDN,请有需要的朋友自行下载。
继承APIView和ViewSetMixin;作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet在开发接口中不经常用。
一、Django介绍Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django 是一个开放源代码的 Web 应用框架,由 Python 写成。Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。Django学习线路Django 采用了 MVT 的软件设计模式,即模型(Model),视图(View)和模板(Template)。这个MVT模式并
本文从nginx快速掌握到使用,gunicorn快速掌握到使用,实现小白快速搭建django项目,并对可能出现的报错进行了分析
uniapp微信小程序订阅消息发送服务通知
Django终端打印SQL语句 1 Setting配置: 2 默认python 使用的MysqlDB连接,Python3 支持支持pymysql 所有需要在app里面的__init__加上下面配置:
url: re_path(&#39;authors/$&#39;, views.AuthorView.as_view()), re_path(&#39;book/(?P\d+)/$&#39;, vie
前提 关于html寻找路线: template 如果在各个APP中存在, Django 会优先找全局template 文件下的html文件,如果全局下的template文件没有相关的html Djan
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
from bs4 import BeautifulSoup#kindeditordef kindeditor(request): s = &#39;&#39;&#39; &lt;li&gt;&lt;s
view.py 配置 html 配置
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault(&#39;content_type&#
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
return HttpResponse(&quot;OK&quot;) 返回一个字符串 return redirect(&quot;/index/&quot;) 返回URL return render
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault(&#39;content_type&#
浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况
自动发送 &gt; 依赖jQuery文件 实例--&gt;GET请求: 手动发送 &gt; 依赖浏览器XML对象(也叫原生ajax) Ajax主要就是使用 【XmlHttpRequest】对象来完成请
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
return HttpResponse(&quot;OK&quot;) 返回一个字符串 return redirect(&quot;/index/&quot;) 返回URL return render