Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to Return Custom JSON in Django REST Framework
Django REST Framework is a powerful toolkit for building 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.
Using 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
Serializers
serializers.FieldType()
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)
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.
Example
In the below example, we have a Book serializer that maps book fields. The BookView class creates an instance of the serializer with sample book data and returns the serialized data using the Response class ?
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(books_data, many=True)
return Response(serializer.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
Let's 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 ?
from rest_framework import renderers, status
from rest_framework.response import Response
from rest_framework.views import APIView
class CustomRenderer(renderers.JSONRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
if isinstance(data, list):
response_data = {'count': len(data), 'results': data}
else:
response_data = 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
We define a view function called books and decorate it with the @api_view decorator to specify that it should handle only GET requests ?
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.response import Response
from rest_framework import status
@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"]}
Project Setup
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 by modifying the settings.py file:
INSTALLED_APPS = [
...
'rest_framework',
'api',
]
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
]
}
Update the urls.py file in the project directory:
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 http://localhost:8000/books/ in your browser, and you should see the custom JSON response containing the list of books.
Conclusion
Django REST Framework provides multiple approaches to return custom JSON responses. Use serializers with Response class for structured data, custom renderers for formatting metadata, and decorators for simplified function-based views.
