When building APIs with Django REST Framework (DRF), two of the most commonly used objects are Request and Response. These objects simplify handling incoming client data and returning API responses.
Unlike standard Django views that use HttpRequest and HttpResponse, DRF provides enhanced versions with additional features specifically designed for API development.
What is a Request Object?
The Request object represents the incoming HTTP request sent by the client.
DRF’s Request object extends Django’s HttpRequest and provides:
- Automatic data parsing
- Support for JSON, form data, and multipart data
- Easy access to query parameters
- Authentication information
- Request headers
Example:
from rest_framework.views import APIView
from rest_framework.response import Response
class EmployeeAPIView(APIView):
def get(self, request):
return Response({
"message": "Request received"
})
Here, request contains all information about the incoming request.
Accessing Request Data
For POST, PUT, and PATCH requests, use request.data.
Example
from rest_framework.views import APIView
from rest_framework.response import Response
class EmployeeCreateAPIView(APIView):
def post(self, request):
name = request.data.get("name")
email = request.data.get("email")
return Response({
"name": name,
"email": email
})
Request Body:
{
"name": "Tarun Kumar",
"email": "tarun@example.com"
}
Response:
{
"name": "Tarun Kumar",
"email": "tarun@example.com"
}
request.data vs request.POST
Django
request.POST
Works mainly with form data.
DRF
request.data
Works with:
- JSON data
- Form data
- Multipart form data
- File uploads
This makes request.data the preferred option in DRF.
Accessing Query Parameters
Query parameters are available through request.query_params.
Example URL:
/api/employees/?department=IT
Code:
from rest_framework.views import APIView
from rest_framework.response import Response
class EmployeeAPIView(APIView):
def get(self, request):
department = request.query_params.get("department")
return Response({
"department": department
})
Response:
{
"department": "IT"
}
Accessing URL Parameters
URL parameters are passed directly to view methods.
from rest_framework.views import APIView
from rest_framework.response import Response
class EmployeeDetailAPIView(APIView):
def get(self, request, employee_id):
return Response({
"employee_id": employee_id
})
URL Configuration:
from django.urls import path
from .views import EmployeeDetailAPIView
urlpatterns = [
path(
'employees/<int:employee_id>/',
EmployeeDetailAPIView.as_view()
),
]
Request:
/api/employees/5/
Response:
{
"employee_id": 5
}
Accessing Authenticated User
DRF makes authenticated user information available through request.user.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class ProfileAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({
"username": request.user.username
})
Accessing Request Headers
Headers can be accessed through request.headers.
class HeaderAPIView(APIView):
def get(self, request):
user_agent = request.headers.get("User-Agent")
return Response({
"user_agent": user_agent
})
What is a Response Object?
The Response object is used to send data back to the client.
DRF automatically converts Python dictionaries, lists, and serializer data into JSON responses.
Import:
from rest_framework.response import Response
Basic Example:
from rest_framework.views import APIView
from rest_framework.response import Response
class WelcomeAPIView(APIView):
def get(self, request):
return Response({
"message": "Welcome to DRF"
})
Response:
{
"message": "Welcome to DRF"
}
Returning Serializer Data
serializer = EmployeeSerializer(employee)
return Response(serializer.data)
DRF automatically converts serializer data into JSON.
Returning Lists
employees = [
{"id": 1, "name": "John"},
{"id": 2, "name": "Tarun"}
]
return Response(employees)
Response:
[
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Tarun"
}
]
Returning Status Codes
DRF provides built-in HTTP status constants.
from rest_framework import status
from rest_framework.response import Response
return Response(
{"message": "Created successfully"},
status=status.HTTP_201_CREATED
)
Common Status Codes:
| Status Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
Returning Error Responses
from rest_framework import status
from rest_framework.response import Response
return Response(
{"error": "Employee not found"},
status=status.HTTP_404_NOT_FOUND
)
Response:
{
"error": "Employee not found"
}
Request vs Response
| Feature | Request | Response |
|---|---|---|
| Purpose | Receives client data | Sends data to client |
| Class | Request | Response |
| Data Access | request.data | Response(data) |
| Query Params | request.query_params | Not Applicable |
| User Info | request.user | Not Applicable |
| Headers | request.headers | Response Headers |
Best Practices
- Use
request.datafor incoming payloads. - Use
request.query_paramsfor filters and search. - Always return responses using
Response(). - Return meaningful HTTP status codes.
- Use serializers for validation before sending responses.
Conclusion
The Request and Response objects are fundamental to Django REST Framework. The Request object simplifies handling incoming client data, while the Response object automatically formats and returns data as JSON. Mastering these objects is essential for building robust and maintainable APIs.