[英]Define pagination page_size per-view in Django Rest Framework
Since version 3.3
it's not longer possible to define page_size on the view, as it's moved to the paginator class. 从版本3.3
,不再可能在视图上定义page_size,因为它已移至paginator类。 related deprecations 相关的弃用
Our API has different page_sizes defined for different views and it feels ambiguous to add new paginator subclasses just to overwrite the page_size attribute. 我们的API为不同的视图定义了不同的page_sizes,添加新的paginator子类只是为了覆盖page_size属性感觉不明确。 I cannot instantiate the paginator class in the view definition and use the __init__
method as it's instantiated here . 我无法在视图定义中实例化paginator类,并使用__init__
方法,因为它在此处实例化。 I could overwrite this and make it a method what returns an instance instantiated with the right parameters, but as its name is not get_pagination_class
, probably it's not a good idea. 我可以覆盖它并使它成为一个方法,返回一个用正确的参数实例化的实例,但由于它的名字不是get_pagination_class
,可能它不是一个好主意。
My question is what would be the cleanest way to dynamically create a paginator class with the proper page_size
attribute set? 我的问题是什么是动态创建具有正确的page_size
属性集的paginator类最干净的方法?
I've seen this question, and I'd like to avoid both of its solutions. 我已经看到了这个问题,我想避免它的两个解决方案。
You can achieve something relatively clean: 你可以实现相对干净的东西:
pagination_class
attribute. 假设您使用pagination_class
属性设置每个类的pagination_class
。 page_size
attribute in your class. 假设您在类中保留了page_size
属性。 In your settings.py
add a global pagination setting: 在您的settings.py
添加全局分页设置:
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': default_page_size,
You can handle with this all the views that have the same page size. 您可以处理具有相同页面大小的所有视图。
For any other view/viewset: 对于任何其他视图/视图集:
class ACustomViewSet(mixins.ListModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet): pagination_class = PageNumberPagination page_size = N pagination_class.page_size = self.page_size
Or you can do this inside a method: 或者您可以在方法中执行此操作:
def list(self, request, *args, **kwargs): self.pagination_class.page_size = self.page_size ...
I finally ended up with customizing it in a custom pagination. 我最终最终定制了自定义分页。 It seemed like the most neat and least hacky solution. 这似乎是最简洁,最不讨厌的解决方案。
The custom pagination 自定义分页
from rest_framework import pagination
class CustomPageNumberPagination(pagination.PageNumberPagination):
"""Custom page number pagination."""
page_size = 30
max_page_size = 10000
page_size_query_param = 'page_size'
def get_page_size(self, request):
"""Get page size."""
# On certain pages, force custom/max page size.
try:
view = request.parser_context['view']
if view.action in [
'custom_page_size_view_1',
'custom_page_size_view_2',
# ...
'custom_page_size_view_n',
]:
return self.max_page_size
except:
pass
return super(CustomPageNumberPagination, self).get_page_size(request)
The view 风景
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import list_route
from .pagination import CustomPageNumberPagination
class MyView(ModelViewSet):
pagination_class = CustomPageNumberPagination
@list_route()
def custom_page_size_view_1(self, request):
"""Custom page size view 1"""
@list_route()
def custom_page_size_view_2(self, request):
"""Custom page size view 2"""
@list_route()
def custom_page_size_view_3(self, request):
"""Custom page size view 3"""
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.