Django rest framework override page_size in ViewSe

2020-06-01 06:28发布

I am having problem with django rest framework pagination. I have set pagination in settings like -

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

Below is my viewset.

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

I want to set different page size for this viewset. I have tried setting page_size and Paginate_by class variables but list is paginated according to PAGE_SIZE defined in settings. Any idea where I am wrong ?

5条回答
一夜七次
2楼-- · 2020-06-01 06:39

In case you are trying to change the "page size" of the LimitOffsetPagination class, you have to override the default_limit variable instead of page_size:

from rest_framework import paginationclass 


CustomLimitOffsetPagination(pagination.LimitOffsetPagination):
    default_limit = 5
查看更多
我命由我不由天
3楼-- · 2020-06-01 06:46

In the case that you want to set a default pagination value, including a max and a param, here is what you do.

1) Create a drf_defaults.py (or any name you choose). I placed it in same dir as 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) In your settings.py, update REST_FRAMEWORK dict, adding the following:

'DEFAULT_PAGINATION_CLASS': 'drf_defaults.DefaultResultsSetPagination',

In the end my REST_FRAMEWORK settings dict looks like:

# 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',
    )
}

Your settings will of course vary! Cheers!

查看更多
冷血范
4楼-- · 2020-06-01 06:47

Use page size query params to provide page size dynamically..

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size_query_param = 'limit'

Set Default pagination class in settings

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

Now in your URL provide limit as a GET parameter..

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

查看更多
萌系小妹纸
5楼-- · 2020-06-01 06:54

Simplest Solution

For LimitOffsetPagination :

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

For PageNumberPagination:

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

For CursorPagination:

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

Full Code:

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

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

Make sure you have DEFAULT_PAGINATION_CLASS in your settings.

查看更多
姐就是有狂的资本
6楼-- · 2020-06-01 06:55

I fixed this by creating custom pagination class. and setting desired pagesize in class. I have used this class as pagination_class in my viewset.

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

I am not sure if there is any easier way for this. this one worked for me. But I think its not good to create new class just to change page_size.

Edit - simple solution is set it like

pagination.PageNumberPagination.page_size = 100 

in ViewSet.

class HobbyCategoryViewSet(viewsets.ModelViewSet):    
    serializer_class = HobbyCategorySerializer
    queryset = UserHobbyCategory.objects.all()
    pagination.PageNumberPagination.page_size = 100 
查看更多
登录 后发表回答