Django rest框架覆盖ViewSet中的page_size

时间:2016-02-16 12:44:12

标签: python django django-rest-framework

我有django休息框架分页的问题。 我在像

这样的设置中设置了分页
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 1

以下是我的观点。

class HobbyCategoryViewSet(viewsets.ModelViewSet):    
    serializer_class = HobbyCategorySerializer
    queryset = UserHobbyCategory.objects.all()

我想为此视图集设置不同的页面大小。我已尝试设置page_size和Paginate_by类变量,但列表根据设置中定义的PAGE_SIZE进行分页。知道我哪里错了吗?

7 个答案:

答案 0 :(得分:15)

我通过创建自定义分页类来修复此问题。并在课堂上设置所需的页面大小。我在我的视图中使用了这个类作为pagination_class。

from rest_framework import pagination

class ExamplePagination(pagination.PageNumberPagination):       
       page_size = 2

class HobbyCategoryViewSet(viewsets.ModelViewSet):    
    serializer_class = HobbyCategorySerializer
    queryset = UserHobbyCategory.objects.all()
    pagination_class=ExamplePagination

我不确定是否有更简单的方法。这个对我有用。但我认为仅仅为了改变page_size而创建新类并不好。

编辑 - 简单的解决方案设置为

pagination.PageNumberPagination.page_size = 100 
在ViewSet中

class HobbyCategoryViewSet(viewsets.ModelViewSet):    
    serializer_class = HobbyCategorySerializer
    queryset = UserHobbyCategory.objects.all()
    pagination.PageNumberPagination.page_size = 100 

答案 1 :(得分:11)

使用页面大小查询参数动态提供页面大小..

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size_query_param = 'limit'

在设置中设置默认分页类

REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'StandardResultsSetPagination',}

现在在您的URL中提供限制作为GET参数..

  

http://example.com/list/?limit=100或25

答案 2 :(得分:1)

如果您尝试更改LimitOffsetPagination类的“页面大小”,则必须覆盖 default_limit 变量而不是 page_size

from rest_framework import paginationclass 


CustomLimitOffsetPagination(pagination.LimitOffsetPagination):
    default_limit = 5

答案 3 :(得分:1)

要设置默认的分页值(包括最大值和参数),请执行以下操作。

1)创建一个drf_defaults.py(或您选择的任何名称)。我将它放在与settings.py相同的目录中:

"""
Django rest framework default pagination
"""
from rest_framework.pagination import PageNumberPagination


class DefaultResultsSetPagination(PageNumberPagination):
    page_size = 50
    page_size_query_param = 'page_size'
    max_page_size = 100000

2)在您的settings.py中,更新REST_FRAMEWORK字典,添加以下内容:

'DEFAULT_PAGINATION_CLASS': 'drf_defaults.DefaultResultsSetPagination',

最后,我的REST_FRAMEWORK设置字典如下:

# http://www.django-rest-framework.org/api-guide/settings/
REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        # 'rest_framework.permissions.AllowAny',  # Use to disable api auth
        # 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
        'permissions.IsAuthenticatedWriteOrReadOnly',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',  # Own oauth server
        'client_authentication.ApiTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ],
    # Enable DRF pagination
    # 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'DEFAULT_PAGINATION_CLASS': 'drf_defaults.DefaultResultsSetPagination',
    'PAGE_SIZE': 50,
    'DEFAULT_RENDERER_CLASSES': (
        # 'rest_framework.renderers.JSONRenderer',  # Swapping out the original renderer
        'lib.drf_renderer.UJSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        # 'rest_framework.parsers.JSONParser',  # Swapping out the original parser
        'lib.drf_parser.UJSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
    ),
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    )
}

您的设置当然会有所不同!干杯!

答案 4 :(得分:0)

最简单的解决方案

对于LimitOffsetPagination:

  viewsets.ModelViewSet.pagination_class.default_limit = 10 #Page limit

对于PageNumberPagination:

    viewsets.ModelViewSet.pagination_class.page_size = 10 #Page limit

对于游标分页:

viewsets.ModelViewSet.pagination_class.page_size = 10 #Page limit

完整代码:

class HobbyCategoryViewSet(viewsets.ModelViewSet):    
        serializer_class = HobbyCategorySerializer
        queryset = UserHobbyCategory.objects.all()

        viewsets.ModelViewSet.pagination_class.default_limit = 10 #Page limit

确保您的设置中包含DEFAULT_PAGINATION_CLASS。

答案 5 :(得分:0)

使用此

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
   page_size = 100
   page_size_query_param = 'page_size'

使用DEFAULT_PAGINATION_CLASS设置键全局应用样式

REST_FRAMEWORK = {
     'DEFAULT_PAGINATION_CLASS': 'your_app*.your_class_file*.StandardResultsSetPagination',
}

用法示例

http://127.0.0.1:8000/produits/api/?page_size=3&page=1

答案 6 :(得分:0)

遇到此问题的任何人都应该阅读这篇文章:http://masnun.rocks/2017/03/20/django-admin-expensive-count-all-queries/

为简化起见,昂贵的COUNT(*)行为有2个触发因素

  1. 分页者。您需要在ModelAdmin类中覆盖它。创建一个类似下面的类(用于Postgres)或

class LargeTablePaginator(Paginator):

    def _get_count(self):
        if getattr(self, '_count', None) is not None:
            return self._count
        
        query = self.object_list.query
        
        

        if not query.where:
            with connections['default'].cursor() as cursor:
                cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
                            [query.model._meta.db_table])
                self._count = int(cursor.fetchone()[0])
        else:
            self._count = super(LargeTablePaginator, self)._get_count()
            
        return self._count

    count = property(_get_count)

然后使用以下命令在您的ModelAdmin中覆盖它:

paginator = LargeTablePaginator
  1. 在Django> 1.8中,您还需要添加:

    show_full_result_count = False

到您的ModelAdmin类。

执行这两个步骤是我能够消除所有count(*)查询的唯一方法。