在Django Rest Framework中定义分页page_size per-view

时间:2016-07-25 12:50:51

标签: python django pagination django-rest-framework

从版本3.3开始,不再可能在视图上定义page_size,因为它已移至paginator类。 related deprecations

我们的API为不同的视图定义了不同的page_sizes,添加新的paginator子类只是为了覆盖page_size属性感觉不明确。我无法在视图定义中实例化paginator类,并使用__init__方法,因为它已实例化here。我可以覆盖它并使它成为一个方法,返回一个用正确的参数实例化的实例,但由于它的名字不是get_pagination_class,可能它不是一个好主意。

我的问题是动态创建具有正确page_size属性集的paginator类的最简洁方法是什么?

我见过this问题,我想避免两种解决方案。

2 个答案:

答案 0 :(得分:5)

你可以做到比较干净的事情:

  • 假设您正在为每个班级设置分页 pagination_class属性。
  • 假设您在班级中保留page_size属性。
  1. settings.py添加全局分页设置:

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': default_page_size,
    

    您可以处理具有相同页面大小的所有视图。

  2. 对于任何其他视图/视图集:

    class ACustomViewSet(mixins.ListModelMixin, 
                         mixins.DestroyModelMixin, 
                         viewsets.GenericViewSet):
    
        pagination_class = PageNumberPagination
        page_size = N
        pagination_class.page_size = self.page_size
    

    或者您可以在方法中执行此操作:

    def list(self, request, *args, **kwargs):
        self.pagination_class.page_size = self.page_size 
        ...
    

答案 1 :(得分:1)

我终于最终在自定义分页中自定义了它。这似乎是最简洁,最不讨厌的解决方案。

自定义分页

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)

视图

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"""