How to Return Custom JSON in Django REST Framework


Django Rest framework is a toolkit that is used to build APIs in Django. It provides features and functionalities to handle HTTP requests and responses in Python. Django Rest framework uses Serializers and Response classes to return custom JSON data. In this article, we will explore different approaches to return custom JSON in Django REST Framework, along with examples.

Serializers and Response Class

Django Rest Framework(DRF) uses serializers to convert complex data types, such as Django models, into JSON, XML, or other content types that can be easily rendered into HTTP responses. To return custom JSON, you can create a serializer class and use the Response class from DRF to create a custom response.

Syntax

  • Serailzers

serializers.FieldType()

Here, Inside the serializer class, we define the fields using the desired field type (e.g., CharField, IntegerField, etc.) and assign them to the corresponding field names.

  • Response class

Response(data, status=status.HTTP_200_OK)

Here,we import the Response class from rest_framework.response module and the status module from rest_framework. We create a response object by passing the data we want to return as a response and the desired HTTP status code, such as HTTP_200_OK, to the Response class constructor.

Example

In the below example, we have a model called Book with fields like title, author, and price. We define a serializer class BookSerializer that maps the Book model fields to the serializer fields. Inside the get method of the BookView class, we create an instance of the serializer with sample book data. We then validate the serializer data and retrieve the serialized data using serializer.data. Finally, we return the serialized data using the Response class with an HTTP 200 status code.

from rest_framework import serializers, status
from rest_framework.response import Response
from rest_framework.views import APIView

class BookSerializer(serializers.Serializer):
    title = serializers.CharField()
    author = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)

class BookView(APIView):
    def get(self, request):
        books_data = [
            {'title': 'Book 1', 'author': 'Author 1', 'price': 9.99},
            {'title': 'Book 2', 'author': 'Author 2', 'price': 14.99},
            {'title': 'Book 3', 'author': 'Author 3', 'price': 19.99}
        ]
        serializer = BookSerializer(data=book_data)
        serializer.is_valid(raise_exception=True)
        response_data = serializer.data

        return Response(response_data, status=status.HTTP_200_OK)

Output

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "title": "Book 1",
        "author": "Author 1",
        "price": "9.99"
    },
    {
        "title": "Book 2",
        "author": "Author 2",
        "price": "14.99"
    },
    {
        "title": "Book 3",
        "author": "Author 3",
        "price": "19.99"
    }
]

Customizing the Response Format

Django Rest Framework provides a way to customize the response format using the renderers module. By default, DRF uses the JSONRenderer class to render responses in JSON format. However, we can define custom renderers to modify the response structure or add additional information.

Example

In the below example, let's say if we want to add metadata to our response, such as the total count of books. We can achieve this by creating a custom renderer and overriding the render method. To do this we create a custom renderer class CustomRenderer by subclassing the JSONRenderer class. Inside the render method, we modify the data by adding a count field that represents the total number of books and a results field that contains the book data. We then call the parent render method to get the JSON response with the modified data.

from rest_framework import renderers

class CustomRenderer(renderers.JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
        response_data = {'count': len(data), 'results': data}
        return super().render(response_data, accepted_media_type, renderer_context)

class BookView(APIView):
    renderer_classes = [CustomRenderer]

    def get(self, request):
        books = ['Book 1', 'Book 2', 'Book 3']
        return Response(books, status=status.HTTP_200_OK)

Output

{"count":3,"results":["Book 1","Book 2","Book 3"]}

Using Response Decorators

Django Rest Framework provides decorators to simplify the process of returning custom responses. The @api_view decorator allows you to specify the desired response format using the renderer_classes argument.

Example

In the below example, we define a view function called books and decorate it with the @api_view decorator to specify that it should handle only GET requests. We also use the @renderer_classes decorator to specify that the response should be rendered using our custom renderer CustomRenderer. Inside the function, we return the list of books as a response.

from rest_framework.decorators import api_view, renderer_classes

@api_view(['GET'])
@renderer_classes([CustomRenderer])
def books(request):
    books = ['Book 1', 'Book 2', 'Book 3']
    return Response(books, status=status.HTTP_200_OK)

Output

{"count":3,"results":["Book 1","Book 2","Book 3"]}

Running the example

To run the example and see the output, you need to set up a Django project with the Django REST Framework installed. Here are the steps:

  • Create a new Django project:

$ django-admin startproject bookstore
  • Create a new Django app within the project:

$ cd bookstore
$ python manage.py startapp api
  • Configure the Django project and app by modifying the settings.py file. Add the following lines to the INSTALLED_APPS and REST_FRAMEWORK sections:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'api',
]

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'api.renderers.CustomRenderer',
    ]
}
  • Define the views and serializers as mentioned in the examples above, inside the views.py and serializers.py files in the api app directory

  • Update the urls.py file in the project directory to include the API endpoints:

from django.urls import path
from api.views import BookView

urlpatterns = [
    path('books/', BookView.as_view()),
]
  • Run the development server

$ python manage.py runserver
  • Visit the URL booksin your browser, and you should see the custom JSON response containing the list of books.

Conclusion

In this article, we discussed how we can return custom JSON in Django Rest Framework using Python Django framework. We explored different approaches to achieve this, including using serializers and the Response class, customizing the response format with renderers, and utilizing decorators for response customization. By using the above methods we can transform and Format the JSON responses accordingly.

Updated on: 18-Jul-2023

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements