Requests & Responses
Django REST Framework introduces its own Request and Response objects that extend Django's standard HttpRequest and HttpResponse respectively. These custom objects provide a more flexible and powerful interface for building web APIs.
Requests
DRF's Request object provides a few crucial properties that make building APIs easier:
.data
request.data is the core of DRF's request processing. It returns the parsed content of the request body (typically a dictionary or list).
- Works for
POST,PUTandPATCHrequests. - Handles parsing multiple content types (JSON, form data, file uploads) transparently based on the Parsers configured for the view.
- Replaces standard Django's
request.POSTandrequest.FILES.
# Instead of this:
data = request.POST
# Do this:
data = request.data.query_params
A more accurately named synonym for request.GET.
Since a GET object typically implies a GET HTTP method, request.query_params makes it clear that you are accessing query string parameters, which can be present on any HTTP request (e.g., POST /api/users/?active=true).
.user & .auth
request.user: Returns an instance ofdjango.contrib.auth.models.User(or your custom user model) if the request is authenticated. Otherwise, it returnsdjango.contrib.auth.models.AnonymousUser.request.auth: Returns any additional authentication context. For example, when using token authentication, this will be the exact token object used to authenticate the request. If the request is unauthenticated, or if no additional context is present, the default value ofrequest.authisNone.
Other Request Properties
| Property | Description |
|---|---|
.parsers | A list of parser instances that the view has configured to process the request body. |
.accepted_renderer | The renderer instance selected by content negotiation to format the response. |
.accepted_media_type | A string representing the accepted media type chosen by the content negotiation phase. |
.authenticators | A list of authenticator instances configured for the view. |
.method | The uppercase string representation of the HTTP method (e.g., 'GET', 'POST'). It transparently handles HTTP method spoofing if enabled. |
.content_type | A string representing the media type of the HTTP body. |
.stream | Returns a stream representing the raw content of the request body. |
NOTE
Since DRF's Request extends Django's HttpRequest, all standard attributes and methods are also available. For example, the request.META and request.session dictionaries are available as normal.
Responses
DRF's Response object extends Django's SimpleTemplateResponse. Instead of passing a pre-rendered string (like HTML or raw JSON) to the response, you pass unrendered, basic Python data structures.
DRF then uses Content Negotiation to determine the appropriate Renderer to format the data for the client.
Instantiating a Response
The standard signature is Response(data, status=None, template_name=None, headers=None, content_type=None).
data: The unrendered data (a dict, list, or primitive) to be serialized.status: The HTTP status code. Defaults to200 OK.template_name: A template name to use ifHTMLRendereris selected.headers: A dictionary of HTTP headers to include in the response.content_type: The content type of the response. Typically, this will be set automatically by the renderer as determined by content negotiation, but there may be some cases where you need to specify the content type explicitly.
TIP
Always use DRF's explicit status code variables (e.g., status.HTTP_400_BAD_REQUEST instead of 400) to keep your views readable and self-documenting.
Example Usage
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
class ExampleView(APIView):
def get(self, request):
data = {"message": "Hello, world!"}
return Response(data, status=status.HTTP_200_OK)
def post(self, request):
# We can read parsed request.data and return unrendered data
received = request.data
if not received:
return Response(
{"error": "No data provided"},
status=status.HTTP_400_BAD_REQUEST
)
return Response(received, status=status.HTTP_201_CREATED)Why Unrendered Data?
By returning native Python structures instead of a raw JSON string, your view remains decoupled from the specific output format. This allows DRF to serve the same view as JSON, XML, or even a browsable HTML interface, depending on the client's Accept header.
Response Properties
| Property | Description |
|---|---|
.data | The unrendered, serialized data provided to the Response when it was instantiated. |
.status_code | The numeric HTTP status code of the response. |
.content | The rendered content of the response. This is typically only available after the .render() method has been called. |
.template_name | The template name supplied when instantiating the response, if any. |
.accepted_renderer | The renderer instance used to render the response. |
.accepted_media_type | The media type string chosen by the content negotiation phase. |
.renderer_context | A dictionary of context information passed to the renderer's .render() method. |
NOTE
Since DRF's Response extends Django's SimpleTemplateResponse, all standard attributes and methods are also available.
