Search code examples
djangodjango-rest-framework

How do I wrap all metadata into a "meta" property?


So I have a paginated list of results. Here's how DRF formats it by default:

{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}

How do I wrap all metadata into a "meta" property so that the response looks like this:

{
    "meta": {
        "count": 1023
        "next": "https://api.example.org/accounts/?page=5",
        "previous": "https://api.example.org/accounts/?page=3",
    },
    "results": [
       …
    ]
}

EDIT: Thanks Alasdair for your answer. Here's how I did it:

from rest_framework import pagination
from rest_framework.response import Response

class CustomPagination(pagination.LimitOffsetPagination):

  def get_paginated_response(self, data):
    return Response({
      'meta': {
        'next': self.get_next_link(),
        'previous': self.get_previous_link(),
        'count': self.count
      },
      'results': data
    })

Solution

  • You need to implement a custom pagination style to wrap all the metadata into a meta property.

    Step-1 Implement a custom pagination class:

    First, we will implement a custom pagination class WrappedMetadataPagination which will inherit from pagination.LimitOffsetPagination. In that, we will override the get_paginated_response() and specify our custom pagination output style.

    class WrappedMetadataPagination(pagination.LimitOffsetPagination):
        """
        This custom pagination class wraps the metadata about the results 
        like 'next', 'previous' and 'next' keys into a dictionary with key as 'meta'.
        """
    
        def get_paginated_response(self, data):
            return Response({
                'meta': { # wrap other keys as dictionary into 'meta' key
                    'next': self.get_next_link(),
                    'previous': self.get_previous_link(),
                    'count': self.count
                },
                'results': data
            })
    

    Step-2 Setup the custom class in DRF settings:

    After implementing the custom class, you need to specify this custom pagination class in your DRF settings.

    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'my_project.my_app.pagination.WrappedMetadataPagination', # specify the custom pagination class
    ...       
    }