When developing APIs or AJAX-based web applications in Django, one of the most common tasks is returning JSON data as a response. Django provides the JsonResponse class to send JSON data easily. However, sometimes we might need to return a custom HTTP status code along with the JSON data.
JsonResponse Syntax:
JsonResponse(data, status=<status_code>)We can change the status code of a JsonResponse by passing the status parameter.
In this article, we’ll explore how to use JsonResponse, why it’s important to set custom status codes, and how to modify the status of a JsonResponse in Django.
What is JsonResponse?
JsonResponse is a subclass of Django’s HttpResponse class that is designed to return JSON-encoded data. It automatically serializes Python dictionaries into JSON format and sets the appropriate content type (application/json) in the HTTP header.
Basic JsonResponse Example
Here’s a simple view that returns a JsonResponse:
from django.http import JsonResponse
def my_view(request):
data = {
'message': 'Hello, Geek!'
}
return JsonResponse(data)
This will return a JSON response with the following content:
{
"message": "Hello, Geek!"
}
By default, JsonResponse returns a status code of 200 (OK).

Why Change the Status Code of a JsonResponse?
In many cases, it’s important to return a specific HTTP status code to indicate the outcome of the request. Common HTTP status codes include:
- 200 OK: The request was successful.
- 201 Created: A new resource has been successfully created.
- 400 Bad Request: There was an error with the request.
- 401 Unauthorized: Authentication is required or failed.
- 403 Forbidden: The server understands the request but refuses to authorize it.
- 404 Not Found: The requested resource could not be found.
- 500 Internal Server Error: The server encountered an unexpected condition.
Setting the correct status code helps clients (e.g., frontend applications or third-party services) understand the outcome of their request and take appropriate actions.
How to Change the Status Code of a JsonResponse in Django
We can change the status code of a JsonResponse by passing the status parameter. The status parameter accepts an integer representing the desired HTTP status code.
Syntax:
JsonResponse(data, status=<status_code>)Example: Returning a 404 Not Found Status
Let’s say we have a view that checks if an object exists in the database. If the object is not found, we want to return a 404 Not Found response.
from django.http import JsonResponse
def my_view(request, item_id):
# Simulate object retrieval
# Let's assume the item is not found
item = None
if item is None:
data = {'error': 'Item not found'}
return JsonResponse(data, status=404)
data = {'message': 'Item found'}
return JsonResponse(data)
In this case, when the item is not found, the response will look like this:
{
"error": "Item not found"
}
And the HTTP status code will be 404.

Example: Returning a 201 Created Status
If we are creating a new resource (e.g., a user or an item) via an API, we would typically return a 201 Created status code to indicate the resource was successfully created.
from django.http import JsonResponse
def create_item(request):
# Simulate item creation
data = {
'message': 'Item successfully created',
# Simulated new item ID
'item_id': 123
}
return JsonResponse(data, status=201)
This would return:
{
"message": "Item successfully created",
"item_id": 123
}
With the HTTP status code 201 Created.

Example: Returning a 400 Bad Request Status
In cases where there is an error in the request (e.g., missing required parameters), we may want to return a 400 Bad Request status.
from django.http import JsonResponse
def submit_form(request):
name = request.GET.get('name')
if not name:
data = {'error': 'Name is required'}
return JsonResponse(data, status=400)
data = {'message': f'Form submitted with name: {name}'}
return JsonResponse(data)
If the name parameter is missing, the response will be:
{
"error": "Name is required"
}
And the HTTP status will be 400 Bad Request.

Example: Returning a 500 Internal Server Error Status
We might want to return a 500 Internal Server Error status when something unexpected happens on the server, such as a failure in processing a request.
from django.http import JsonResponse
def risky_operation(request):
try:
# This will raise a ZeroDivisionError
result = 1 / 0
except Exception as e:
data = {'error': 'Internal server error', 'details': str(e)}
return JsonResponse(data, status=500)
data = {'message': 'Operation successful'}
return JsonResponse(data)
If the operation fails, the response will be:
{
"error": "Internal server error",
"details": "division by zero"
}
And the HTTP status will be 500 Internal Server Error.

Using safe=False for Non-Dictionary Data
By default, JsonResponse expects the data passed to it to be a dictionary. If we want to return a list or another data structure like Python Lists, we need to set the safe parameter to False.
Example: Returning a List with a Custom Status
from django.http import JsonResponse
def get_items(request):
items = ['apple', 'banana', 'orange']
return JsonResponse(items, safe=False, status=200)
This will return:
["apple", "banana", "orange"]With the HTTP status 200 OK.

Using Custom Headers with JsonResponse
Sometimes, we might need to include custom HTTP headers in our response. We can do this by modifying the JsonResponse object after it’s created.
from django.http import JsonResponse
def my_view(request):
data = {'message': 'Hello, world!'}
response = JsonResponse(data, status=200)
# Adding custom headers
response['Custom-Header'] = 'CustomValue'
return response
In this case, the response will include the custom header Custom-Header with the value CustomValue.
Output:

Conclusion
Django's JsonResponse makes it easy to return JSON data in our views. However, it’s often important to return the appropriate HTTP status code to reflect the result of the request. By using the status parameter in JsonResponse, we can control the HTTP status code returned to the client.
Key Points:
- JsonResponse is used to return JSON data with a default status of 200 OK.
- We can modify the status code by using the status parameter.
- Common status codes include 404 Not Found, 201 Created, 400 Bad Request, and 500 Internal Server Error.
- We can return non-dictionary data (like lists) by setting safe=False.
- Custom headers can be added to the JsonResponse object.
With this knowledge, we can effectively handle various scenarios in our Django applications by using JsonResponse with the appropriate status codes.