Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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. I cannot instantiate the paginator class in the view definition and use the __init__ method as it's instantiated here. 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.

My question is what would be the cleanest way to dynamically create a paginator class with the proper page_size attribute set?

I've seen this question, and I'd like to avoid both of its solutions.

like image 353
fodma1 Avatar asked Jul 25 '16 12:07

fodma1


People also ask

How does pagination work in Django REST framework?

Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular APIView , you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the mixins. ListModelMixin and generics.

What is view in Django REST framework?

Django views facilitate processing the HTTP requests and providing HTTP responses. On receiving an HTTP request, Django creates an HttpRequest instance, and it is passed as the first argument to the view function. This instance contains HTTP verbs such as GET, POST, PUT, PATCH, or DELETE.

What is Paginator Django?

Django provides a few classes that help you manage paginated data – that is, data that's split across several pages, with “Previous/Next” links. These classes live in django/core/paginator.py. For examples, see the Pagination topic guide.

Does pagination improve performance Django?

Additionally, switching to keyset pagination will improve the performance of page lookups and make them work in constant time. Django makes it easy to alter its default configuration, giving you the power to build a performant solution for pagination in Django.


1 Answers

You can achieve something relatively clean:


  • Assuming you are setting the pagination per class with the pagination_class attribute.
  • Assuming that you keep the page_size attribute in your class.

  1. In your settings.py add a global pagination setting:

    '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.

  2. 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 
        ...
    
like image 165
John Moutafis Avatar answered Oct 29 '22 11:10

John Moutafis