【问题标题】:Define pagination page_size per-view in Django Rest Framework在 Django Rest Framework 中定义分页 page_size per-view
【发布时间】:2016-11-28 19:50:56
【问题描述】:

自版本3.3 起,不再可能在视图上定义 page_size,因为它已移至分页器类。 related deprecations

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

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

我已经看到this 的问题,我想避免这两种解决方案。

【问题讨论】:

  • 他们改变了这个真的超级烦人,它一定是最常见的分页改变之一,你不应该仅仅为了改变这个参数而派生新的类。

标签: python django pagination django-rest-framework


【解决方案1】:

你可以实现一些相对干净的东西:


  • 假设您使用 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 
        ...
    

【讨论】:

  • 嗨 John,我在这段代码中遇到了一些问题,基本上我现在有 3 天时间学习 python,因为我被分配修复一个 Python 项目,我对语言还不太熟悉,所以我能问你应该在哪里定义Nselfclass ACustomViewSet 中?如果我有mixins.CreateModelMixin 而不是mixins.DestroyModelMixin,会有什么麻烦吗?谢谢
  • 嘿 @Frakcool, 1) self 不需要在 python 类中明确定义。 2) N 可以是任何正整数,表示响应每页有多少结果。 3) DestroyModelMixin 提供了一个删除方法,CreateModelMixin 提供了一个创建方法,所以只使用其中一个或两者都不会有问题!希望这会有所帮助:)
  • 谢谢约翰,从 1) Python 给我一个Undefined variable: self,从 2 和 3 我明白了,你认为self 的问题是什么?那我会继续找的……哦等等!我想我可以说:pagination_class.page_size = page_size 不是吗?
  • 很好!非常感谢约翰! 1+ :) 我仍然可以通过= 右侧的self 得到它,但我可以从两边删除它
  • 糟糕,抱歉,我使用的是 GenericView 而不是 GenericViewSet,如果在 GenericView 中使用,它似乎会为所有视图设置 page_size。
【解决方案2】:

我最终在自定义分页中对其进行了自定义。这似乎是最简洁、最不老套的解决方案。

自定义分页

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

【讨论】:

    猜你喜欢
    • 2015-05-18
    • 1970-01-01
    • 2023-02-20
    • 2016-09-14
    • 1970-01-01
    • 2015-03-02
    • 2015-06-28
    • 2018-01-06
    相关资源
    最近更新 更多