Django Rest Framework源码剖析(七)-----分页
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0"> |
http://api.example.org/accounts/?page=4
http://api.example.org/accounts/?page=4&page_size=100
</span><span style="color: #800000;">"""</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> The default page size.</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Defaults to `None`,meaning pagination is disabled.</span>
page_size =<span style="color: #000000;"> api_settings.PAGE_SIZE <span style="color: #ff6600;">#每页显示个数配置,可以在setting中配置,也可以在类里,当前类>全局(settings)</span>
django_paginator_class </span>=<span style="color: #000000;"> DjangoPaginator <span style="color: #ff6600;"># 本质使用django自带的分页组件
</span></span><span style="color: #008000;">#</span><span style="color: #008000;"> Client can control the page using this query parameter.</span>
page_query_param = <span style="color: #800000;">'</span><span style="color: #800000;">page</span><span style="color: #800000;">' <span style="color: #ff6600;"># url中的页码key配置</span></span><span style="color: #000000;">
page_query_description </span>= _(<span style="color: #800000;">'</span><span style="color: #800000;">A page number within the paginated result set.</span><span style="color: #800000;">'</span><span style="color: #000000;">) <span style="color: #ff6600;"> # 描述
</span></span><span style="color: #008000;">#</span><span style="color: #008000;"> Client can control the page size using this query parameter.</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Default is 'None'. Set to eg 'page_size' to enable usage.</span>
page_size_query_param =<span style="color: #000000;"> None <span style="color: #ff6600;"> # url中每页显示个数的key配置</span>
page_size_query_description </span>= _(<span style="color: #800000;">'</span><span style="color: #800000;">Number of results to return per page.</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Set to an integer to limit the maximum page size the client may request.</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Only relevant if 'page_size_query_param' has also been set.</span>
max_page_size =<span style="color: #000000;"> None <span style="color: #ff6600;"> # 最多显示个数配置</span>
last_page_strings </span>= (<span style="color: #800000;">'</span><span style="color: #800000;">last</span><span style="color: #800000;">'</span><span style="color: #000000;">,)
template </span>= <span style="color: #800000;">'</span><span style="color: #800000;">rest_framework/pagination/numbers.html</span><span style="color: #800000;">' <span style="color: #ff6600;"># 渲染的模板</span></span><span style="color: #000000;">
invalid_page_message </span>= _(<span style="color: #800000;">'</span><span style="color: #800000;">Invalid page.</span><span style="color: #800000;">'</span><span style="color: #000000;">) <span style="color: #ff6600;"> # 页面不合法返回的信息,当然我们也可以自己定制
</span></span><span style="color: #0000ff;">def</span> paginate_queryset(self,queryset,view=<span style="color: #000000;">None): <span style="color: #ff6600;"># 获取分页数据
</span></span><span style="color: #800000;">"""</span><span style="color: #800000;">
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;">"""</span><span style="color: #000000;">
page_size </span>=<span style="color: #000000;"> self.get_page_size(request) <span style="color: #ff6600;"># 调用get_page_size 获取当前请求的每页显示数量
</span></span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> page_size:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> None
paginator </span>=<span style="color: #000000;"> self.django_paginator_class(queryset,page_size)
page_number </span>= request.query_params.get(self.page_query_param,1<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> page_number <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.last_page_strings:
page_number </span>=<span style="color: #000000;"> paginator.num_pages
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
self.page </span>=<span style="color: #000000;"> paginator.page(page_number)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> InvalidPage as exc:
msg </span>=<span style="color: #000000;"> self.invalid_page_message.format(
page_number</span>=page_number,message=<span style="color: #000000;">six.text_type(exc)
)
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> NotFound(msg)
</span><span style="color: #0000ff;">if</span> paginator.num_pages > 1 <span style="color: #0000ff;">and</span> self.template <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> The browsable API should display pagination controls.</span>
self.display_page_controls =<span style="color: #000000;"> True
self.request </span>=<span style="color: #000000;"> request
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> list(self.page)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_paginated_response(self,data):
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> Response(OrderedDict([
(</span><span style="color: #800000;">'</span><span style="color: #800000;">count</span><span style="color: #800000;">'</span><span style="color: #000000;">,self.page.paginator.count),(</span><span style="color: #800000;">'</span><span style="color: #800000;">next</span><span style="color: #800000;">'</span><span style="color: #000000;">,self.get_next_link()),(</span><span style="color: #800000;">'</span><span style="color: #800000;">previous</span><span style="color: #800000;">'</span><span style="color: #000000;">,self.get_previous_link()),(</span><span style="color: #800000;">'</span><span style="color: #800000;">results</span><span style="color: #800000;">'</span><span style="color: #000000;">,data)
]))
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_page_size(self,request):
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> self.page_size_query_param:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> _positive_int(
request.query_params[self.page_size_query_param],strict</span>=<span style="color: #000000;">True,cutoff</span>=<span style="color: #000000;">self.max_page_size
)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> (KeyError,ValueError):
</span><span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.page_size
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_next_link(self):
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.page.has_next():
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> None
url </span>=<span style="color: #000000;"> self.request.build_absolute_uri()
page_number </span>=<span style="color: #000000;"> self.page.next_page_number()
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> replace_query_param(url,self.page_query_param,page_number)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_previous_link(self):
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.page.has_previous():
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> None
url </span>=<span style="color: #000000;"> self.request.build_absolute_uri()
page_number </span>=<span style="color: #000000;"> self.page.previous_page_number()
</span><span style="color: #0000ff;">if</span> page_number == 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> remove_query_param(url,self.page_query_param)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> replace_query_param(url,page_number)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_html_context(self):
base_url </span>=<span style="color: #000000;"> self.request.build_absolute_uri()
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> page_number_to_url(page_number):
</span><span style="color: #0000ff;">if</span> page_number == 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> remove_query_param(base_url,self.page_query_param)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> replace_query_param(base_url,page_number)
current </span>=<span style="color: #000000;"> self.page.number
final </span>=<span style="color: #000000;"> self.page.paginator.num_pages
page_numbers </span>=<span style="color: #000000;"> _get_displayed_page_numbers(current,final)
page_links </span>=<span style="color: #000000;"> _get_page_links(page_numbers,current,page_number_to_url)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">previous_url</span><span style="color: #800000;">'</span><span style="color: #000000;">: self.get_previous_link(),</span><span style="color: #800000;">'</span><span style="color: #800000;">next_url</span><span style="color: #800000;">'</span><span style="color: #000000;">: self.get_next_link(),</span><span style="color: #800000;">'</span><span style="color: #800000;">page_links</span><span style="color: #800000;">'</span><span style="color: #000000;">: page_links
}
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> to_html(self):
template </span>=<span style="color: #000000;"> loader.get_template(self.template)
context </span>=<span style="color: #000000;"> self.get_html_context()
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> template.render(context)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_schema_fields(self,view):
</span><span style="color: #0000ff;">assert</span> coreapi <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None,<span style="color: #800000;">'</span><span style="color: #800000;">coreapi must be installed to use `get_schema_fields()`</span><span style="color: #800000;">'</span>
<span style="color: #0000ff;">assert</span> coreschema <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None,<span style="color: #800000;">'</span><span style="color: #800000;">coreschema must be installed to use `get_schema_fields()`</span><span style="color: #800000;">'</span><span style="color: #000000;">
fields </span>=<span style="color: #000000;"> [
coreapi.Field(
name</span>=<span style="color: #000000;">self.page_query_param,required</span>=<span style="color: #000000;">False,location</span>=<span style="color: #800000;">'</span><span style="color: #800000;">query</span><span style="color: #800000;">'</span><span style="color: #000000;">,schema</span>=<span style="color: #000000;">coreschema.Integer(
title</span>=<span style="color: #800000;">'</span><span style="color: #800000;">Page</span><span style="color: #800000;">'</span><span style="color: #000000;">,description</span>=<span style="color: #000000;">force_text(self.page_query_description)
)
)
]
</span><span style="color: #0000ff;">if</span> self.page_size_query_param <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
fields.append(
coreapi.Field(
name</span>=<span style="color: #000000;">self.page_size_query_param,schema</span>=<span style="color: #000000;">coreschema.Integer(
title</span>=<span style="color: #800000;">'</span><span style="color: #800000;">Page size</span><span style="color: #800000;">'</span><span style="color: #000000;">,description</span>=<span style="color: #000000;">force_text(self.page_size_query_description)
)
)
)
</span><span style="color: #0000ff;">return</span> fields</pre>
而第二种LimitOffsetPagination,使用场景是当数据量比较大时候,只关心其中某一部分数据,推荐使用。
CursorPagination类型分页相对于PageNumberPagination有点在于,它避免了人为在url中自己传入参数进行页面的刷新(因为url不规则),缺点也显而易见只能进行上下页的翻阅。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
- 在 Delphi 下使用 DirectSound (2): 查看设备性能
- Delphi的TADOConnection线程安全吗?
- delphi – 如何访问私人方法没有帮助者?
- 数据处理-Spring Batch Scaling and Parallel Processing
- 有关golang package中init方法的多处定义及运行顺序问题
- php – Composer安装在Laravel 5上崩溃(仅限生产)
- golang从腾讯 lbs 获取全国省市区及经纬度坐标
- [VB.NET]急!!!! 实现矩阵转置,即将矩阵的行,列互换,一个3行
- 从Delphi开始学Cocos2dx-3.0[5]:鼠标按下移动弹起与单点触摸
- delphi – 扫描代码并提供调用给定函数的函数列表的任何工具