Official original text link this series of articles github address reprint please indicate the source

paging

The REST Framework includes support for customizable paging styles. This allows you to split larger result sets into separate data pages.

Paging API support:

  • As part of the response content in the form of paging links.
  • Included in the header of the response as a paginated link, as inContent-RangeLink.

The built-in style is currently in the form of paging links as part of the response content. This style is easier to access when using browsable apis.

Paging is only done automatically if you use a generic view or set of views. If you are using a regular APIView, you will need to call the paging API yourself to ensure that the paging response is returned. See the source code for the mixins.ListModelMixin and Generics. GenericAPIView classes for examples.

You can turn off paging by setting the paging class to None.

Setting paging Style

Page styles can be set globally using DEFAULT_PAGINATION_CLASS and PAGE_SIZE setting key. For example, to use the built-in limit/offset page, you could do this:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'.'PAGE_SIZE': 100
}
Copy the code

Note that you need to set the paging class and the page size that should be used. By default, DEFAULT_PAGINATION_CLASS and PAGE_SIZE are both None.

You can also set paging classes on a single view using the Pagination_class property. Typically, you want to use the same paging style throughout the API, but you may want to change aspects of paging, such as the default or maximum page size, on a per-view basis.

Change the paging style

If you want to modify a specific aspect of the paging style, you need to inherit one of the paging classes and set the properties you want to change.

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size'
    max_page_size = 10000

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 1000
Copy the code

You can then apply the new style to the view using the.pagination_class property:

class BillingRecordsView(generics.ListAPIView):
    queryset = Billing.objects.all()
    serializer_class = BillingRecordsSerializer
    pagination_class = LargeResultsSetPagination
Copy the code

Or use DEFAULT_PAGINATION_CLASS setting key to apply the style globally. Such as:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
}
Copy the code

API reference

PageNumberPagination

This paging style accepts a page number value in the request query parameter.

Request:

GET https://api.example.org/accounts/?page=4
Copy the code

Response:

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5"."previous": "https://api.example.org/accounts/?page=3"."results": [...]. }Copy the code

Setup

To enable the PageNumberPagination style globally, use the following configuration and set PAGE_SIZE as required:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination'.'PAGE_SIZE': 100
}
Copy the code

If you are using a subclass of GenericAPIView, you can also set the Pagination_class property to select PageNumberPagination on a per-view basis.

Configuration

The PageNumberPagination class contains several properties that can be overridden to modify the paging style.

To set these properties, you should inherit the PageNumberPagination class and then enable your custom pagination class as above.

  • django_paginator_class– The Django Paginator class to use. The default isdjango.core.paginator.PaginatorShould be fine for most use cases.
  • page_size– Specifies a numeric value for the page size. If set, it overwritesPAGE_SIZESetting. The default value andPAGE_SIZESetting key is the same.
  • page_query_param– A string value specifying the name of the query parameter used for the paging control.
  • page_size_query_param– A string value specifying the name of the query parameter, allowing the client to set the page size per request. The default isNone, indicating that the client may have no control over the requested page size.
  • max_page_size– A numeric value that indicates the maximum allowed page size. This property is available only inpage_size_query_paramAlso valid when set.
  • last_page_strings– List of strings or tuples that specify possible relationshipspage_query_paramValues used together to request the final page in the collection. The default is('last',)
  • template– The name of the template to use when rendering paging controls in the browsable API. May be overridden to modify the render style, or set toNoneTo completely disable the HTML paging control. The default is"rest_framework/pagination/numbers.html".

LimitOffsetPagination

This paging style reflects the syntax used when looking up multiple database records. The client contains limit and offset query parameters. Limit indicates the maximum number of items to return and is equivalent to page_size in other styles. Offset specifies the relationship between the starting position of the query and the complete set of unclassified items.

Request:

GET https://api.example.org/accounts/?limit=100&offset=400
Copy the code

Response:

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?limit=100&offset=500"."previous": "https://api.example.org/accounts/?limit=100&offset=300"."results": [...]. }Copy the code

Setup

To enable the LimitOffsetPagination style globally, use the following configuration:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}
Copy the code

Alternatively, you can set a PAGE_SIZE key. If the PAGE_SIZE parameter is used, the limit query parameter is optional and may be ignored by the client.

If you subclass GenericAPIView, you can also set the pagination_class property to select LimitOffsetPagination on a per-view basis.

Configuration

The LimitOffsetPagination class contains several properties that can be overridden to modify the paging style.

To set these properties, inherit the LimitOffsetPagination class and then enable your custom pagination class as above.

  • default_limit– A numeric value specifying the limit not provided by the client in the query parameters. The default value andPAGE_SIZESetting key is the same.
  • limit_query_param– A string value indicating the name of the “limit” query parameter. The default is'limit'.
  • offset_query_param– A string value indicating the name of the “offset” query parameter. The default is'offset'.
  • max_limit– A numeric value indicating the maximum allowable limit that a client can request. The default isNone.
  • template– The name of the template to use when rendering paging controls in the browsable API. May be overridden to modify the render style, or set toNoneTo completely disable the HTML paging control. The default is"rest_framework/pagination/numbers.html".

CursorPagination

Cursor based paging provides an opaque “cursor” indicator that clients can use to scroll through result sets. This paging style provides only forward and reverse controls and does not allow clients to navigate to arbitrary locations.

Cursors based paging requires a unique, unchanging order of items in the result set. This sort can often be a creation timestamp on the record, as this ensures a consistent sort.

Cursors based paging is more complex than other schemes. It also requires that result sets be rendered in a fixed order and does not allow clients to index result sets arbitrarily. But it does offer the following benefits:

  • Provide a consistent paging view. When used correctlyCursorPaginationEnsure that clients do not see the same item when paging, even if other clients are inserting new items during paging.
  • Support for using very large data sets. Using offset-based paging styles can become inefficient or unusable when paging with very large data sets. The cursor based paging scheme has a fixed time property and does not slow down as the data set size increases.

Details and Limitations

Proper use of cursor based paging requires a little attention to detail. You need to think about the order in which you want to apply the scheme. The default is “-created”. This assumes that there must be an “Created” timestamp field on the model instance and that a “timeline” style paging view is rendered, with the most recently added item being the first.

You can modify ordering by overriding the ‘ordering’ property on the paging class or by using the OrderingFilter class with CursorPagination. When working with OrderingFilter, you should consider limiting the fields that users can sort.

Proper use of cursor paging should have a sort field that meets the following criteria:

  • Should be a constant value when created, such as a timestamp, slug, or other field that is set only once.
  • Should be unique, or almost unique. Millisecond precision timestamps are a good example. This implementation of cursor paging uses an intelligent “position + offset” style that allows it to correctly support values that are not strictly unique for sorting.
  • Should be a non-null value that can be forced as a string.
  • Should not be a float. Precision errors can easily lead to wrong results. Tip: Use decimals instead. (If you already have a float field and must paginate it, you can find an example of using decimals to limit precision here.)
  • This field should have a database index.

Using sorted fields that do not meet these constraints will usually still work, but you will lose some of the benefits of cursor paging.

Setup

To enable the CursorPagination style globally, use the following configuration, modifying PAGE_SIZE as needed:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination'.'PAGE_SIZE': 100
}
Copy the code

If you subclass GenericAPIView, you can also set the pagination_class property to select CursorPagination on a per-view basis.

Configuration

The CursorPagination class contains properties that can be overridden to modify the paging style.

To set these properties, you should inherit the CursorPagination class and then enable your custom pagination class as above.

  • page_size= specifies a numeric value for the page size. If set, it overwritesPAGE_SIZESettings. The default value andPAGE_SIZESetting key is the same.
  • cursor_query_param= a string value specifying the name of the cursor query parameter. The default is'cursor'.
  • ordering= This should be a string or list of strings specifying the fields to which cursor based paging will be applied. Such as:ordering = 'slug'. The default is-created. This value can also be used on the viewOrderingFilterTo cover.
  • template= the name of the template to use when rendering paging controls in the browsable API. May be overridden to modify the render style, or set toNoneTo completely disable the HTML paging control. The default is"rest_framework/pagination/previous_and_next.html".

Custom paging styles

To create a custom paging serialization class, You should inherit pagination. BasePagination and override paginate_queryset (self, queryset, request, View =None) and get_paginated_response(self, data) methods:

  • paginate_querysetMethods are passed to the initial query set and should return an iterable containing only the data from the request page.
  • get_paginated_responseMethod passes serialized page data and returns oneResponseInstance.

Note that the paginate_querySet method can set the state on the paging instance, and then the get_paginATED_Response method can use it.

Take a chestnut

Suppose we want to replace the default paging output style with a modified format that contains nested “links” keys (containing previous page, next page links). We can specify a custom paging class like this:

class CustomPagination(pagination.PageNumberPagination):
    def get_paginated_response(self, data):
        return Response({
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'results': data
        })
Copy the code

Then we need to set up the custom class in the configuration:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.CustomPagination'.'PAGE_SIZE': 100
}
Copy the code

Note that if you are concerned with displaying the order of keys in a browsable API, it is optional to use OrderedDict when building the body of the paging response.

Use your custom paging class

To use your custom paging class by default, use DEFAULT_PAGINATION_CLASS setting:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination'.'PAGE_SIZE': 100
}
Copy the code

The API response of the list endpoint will now contain a Link header, rather than including the paging Link as part of the response body.

Paging and mode

You can also make paging controls automatically generated for patterns provided by the REST Framework by implementing the get_schema_fields() method. This method should have the following signature:

get_schema_fields(self, view)

The method should return a list of CoreApi.Field instances.


Custom paging style, using the ‘Link’ header


HTML page control

By default, using a paging class causes HTML paging controls to appear in a browsable API. There are two built-in display styles. The PageNumberPagination and LimitOffsetPagination classes display a list of page numbers containing the previous and next controls. The CursorPagination class displays a simpler style, showing only the previous and next controls.

Custom control

You can override templates that render HTML paging controls. The two built-in styles are:

  • rest_framework/pagination/numbers.html
  • rest_framework/pagination/previous_and_next.html

Providing templates with these paths in the global template directory overrides the default rendering of the related paging class.

Alternatively, you can set Template =None as a property of an existing class by completely disabling HTML paging controls on subclasses of the class. Then, you need to configure your DEFAULT_PAGINATION_CLASS setting key to use your custom class as the default paging style.

Low-level apis

The low-level API used to determine whether a paging class should display controls is exposed as the Display_PAGe_Controls property on a paging instance. If you need to display HTML paging controls, the custom paging class should be set to True in the paginate_querySet method.

The.to_html() and.get_html_context() methods can also be overridden in custom paging classes to further customize how controls are rendered.