DRF自定义分页中page=DEFAULT_PAGE的作用解析
DRF自定义分页代码解析
一、page = DEFAULT_PAGE的实际作用
你代码里的page = DEFAULT_PAGE这个类属性完全没用——DRF的PageNumberPagination父类根本不认这个属性,不会用它来设置默认页码:
- 父类的默认页码逻辑是写死在
get_page_number方法里的:如果请求没传page参数,就默认用第1页,完全不会读取你定义的page类属性。 - 这个属性属于冗余代码,删了对分页逻辑没有任何影响,DRF该怎么处理还是怎么处理。
二、为什么get_paginated_response里不能用self.page当默认值
你在响应的page字段里写int(self.request.GET.get('page', DEFAULT_PAGE)),没法直接用self.page当默认值,核心原因有两个:
self.page不是数字:self.page是Django生成的Page对象实例,里面包含了分页后的数据集、总页数这些信息,不是单纯的页码数字。要是直接把它当默认值转int,肯定会报错,要拿页码得用self.page.number。- 实际分页页码和你想的默认值不匹配:就算你用
self.page.number,它的值也不是你设的DEFAULT_PAGE=9——因为DRF默认会把没传page的请求处理成第1页,所以self.page.number此时是1,不是9。你写DEFAULT_PAGE是想让响应里显示默认页码9,但这和实际返回的第1页数据是矛盾的,会导致响应信息和实际数据不对应。
正确实现默认页码为9的写法
要是你确实想把默认页码改成9,得重写get_page_number方法,而不是瞎设类属性:
from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response DEFAULT_PAGE = 9 DEFAULT_PAGE_SIZE = 9 class CustomPagination(PageNumberPagination): page_size = DEFAULT_PAGE_SIZE page_size_query_param = 'page_size' def get_page_number(self, request, paginator): # 重写方法,把默认页码换成DEFAULT_PAGE page_number = request.query_params.get(self.page_query_param, DEFAULT_PAGE) if page_number in self.last_page_strings: page_number = paginator.num_pages return page_number def get_paginated_response(self, data): return Response({ 'links': { 'next': self.get_next_link(), 'previous': self.get_previous_link() }, 'total': self.page.paginator.count, # 这里直接用self.page.number就行,已经是处理后的正确页码 'page': self.page.number, 'page_size': int(self.request.GET.get('page_size', self.page_size)), 'results': data })
这么改之后:
- 没传
page参数的请求会自动处理成第9页,self.page.number就是9,响应里的page字段也能正确返回9。 - 不用再手动从
request.GET里取页码,直接用self.page.number就能拿到实际处理的页码,不会出现响应和数据不匹配的问题。
内容的提问来源于stack exchange,提问作者saman barjawand
相关产品推荐
相关产品推荐

