Request and Response Objects in Django REST Framework

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 CodeMeaning
200OK
201Created
204No Content
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal 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

FeatureRequestResponse
PurposeReceives client dataSends data to client
ClassRequestResponse
Data Accessrequest.dataResponse(data)
Query Paramsrequest.query_paramsNot Applicable
User Inforequest.userNot Applicable
Headersrequest.headersResponse Headers

Best Practices

  • Use request.data for incoming payloads.
  • Use request.query_params for 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.