HttpResponse Django – HTTP Response Explained with Examples

Django is a web application framework which means it is heavily used in scenarios that include receiving and sending HTTP requests. That is one of the main functionalities Django gives us. We’ll see how to define and return the HTTP response using the HttpResponse Django class in this post. You can also find a few helpful examples at the end of this post.

For those who only want the syntax of returning the HttpResponse, you can use the following snippet.

from django.http import HttpResponse

def http_response_view(request):
    content = '<p>dummy content</p>'
    return HttpResponse(content)

Django Request-Response Cycle

Before explaining what is and how to return a HTTP response in Django, let’s first recall how the request-response cycle looks like in Django. The standard request-response cycle involves the following steps:

  1. A client sends the HTTP request.
  2. Request is processed by request middlewares.
  3. Request is passed to the URL Router.
  4. View function accepts the request.
  5. View function forwards the request data to the business layer.
  6. View function defines the HTTP response and sends it back.
  7. Response is processed by context processors and template renderers.
  8. The response is processed by response middlewares.
  9. Client gets the HTTP response.

The simplified Django request-response cycle is also shown in the image below.

Http Response Django - Request Response Cycle

In the example above, we are particularly interested in step 6, in which we define and return an HTTP response. For this, we will want to use Django’s HttpResponse class.

How to send the HTTP response? – Django HttpResponse Explained

As we mentioned earlier, a Django view takes a web request and returns a web response. After the request is captured, Django creates an HttpRequest object with associated metadata that is then processed by middlewares and backend logic. After processing the request, the server needs to return a response to the client. The response can be anything: HTML, JSON, binary data, error, etc.

Django’s HttpResponse class is used to define an HTTP response. It comes from the django.http module, and it contains a set of predefined attributes and methods you can use to return the appropriate response to the client. You will usually use this class inside a view function, for example, in views.py

To successfully send the HttpResponse object to the client, you must import it from the django.http module and return it from the view function. Below you can see how the HttpResponse constructor looks like:

HttpResponse(content=b'', content_type=None, status=200, reason=None, charset=None, headers=None)
  • content – It can be an iterator, bytestring, memoryview or string.
  • content_type – Defines what MIME type is returned (by default is set to text/html).
  • status – HTTP status code (described in the section below).
  • reason – HTTP response phrase.
  • charset – The charset in which the response will be encoded.
  • headers – HTTP headers for the response.

Here’s an example of a view function inside the views.py that returns the HttpResponse with some simple HTML. We defined only content here; everything else is set to default.

# views.py
from django.http import HttpResponse

def http_response_view(request):
    return HttpResponse('<h1>This is a H1 heading!</h1>') 

Let’s also add the URL path for the newly created view function inside the urls.py file.

from django.urls import path
from .views import http_response_view

urlpatterns = [
    path('simple/', http_response_view),
]

Now, run the development server with the python manage.py runserver command and access the http://127.0.0.1:8000/simple/. You’ll see the This is a H1 heading! heading in the browser.

Example of a page rendered after the Django Http Response was returned.

Http Response Django – Status Codes

Each HTTP response needs to declare a status code to make it easy for client to determine whether the request was successfully processed or not. You can find the full list of status codes here, but the most commonly used are:

  • 200 OK – The request succeeded.
  • 201 Created – New resource was successfully created.
  • 204 No Content – There is no content to send back to the client for this request.
  • 301 Moved Permanently – The request resource was moved to another URL. The new URL is included in the response.
  • 400 Bad Request – The request was incorrectly defined on the client side.
  • 401 Unauthorized – The client is not authenticated to get the response.
  • 403 Forbidden – The client does not have the necessary rights to get the response.
  • 404 Not Found – The server can not find the requested resource.
  • 500 Internal Server Error – The server encountered a situation/error and did not know how to handle it.
  • 502 Bad Gateway – The server got an invalid response from another server.
NOTE - Responses are grouped into five classes based on status codes:
- Informational responses (100 - 199)
- Successful responses (200 - 299)
- Redirection responses (300 - 399)
- Client error responses (400 - 499)
- Server error responses (500 - 599)

HttpResponse – Django examples

In this section, we’ll show a few simple examples of using the HttpResponse in different scenarios.

1. Use HttpResponse to return plain text

Sometimes you’ll have to return only the plain text in the response. Similar to the example at the beginning of the article, you only need to pass the string to the HttpResponse object and change the content_type to text/plain.

# views.py
from django.http import HttpResponse

def plain_text_view(request):
    return HttpResponse('This is some text.', content_type='text/plain') 

2. Use HttpResponse to return JSON data

Often, and especially if you are designing a REST API, you’ll have to return JSON data to the client. Django has a special HttpResponse subclass called JsonResponse that makes this easy for you.

# views.py
from django.http import JsonResponse

def json_data_view(request):
    return JsonResponse({'dummy_key': 'dummy_value'}) 

3. Use HttpResponse to return data as a File attachment

The browser treats all HTTP responses differently depending on the defined Content-Type header. If you want, for example, to make the browser download the JSON response data from the above example, you’ll need to set the Content-Type to application/json. Also, you’ll have to set the Content-Disposition header too. See the example below:

# views.py
from django.http import HttpResponse

def json_data_as_attachment_view(request):
    json_data = {'dummy_key': 'dummy_value'}
    return HttpResponse(
        json_data,
        headers={
            'Content-Type': 'application/json',
            'Content-Disposition': 'attachment; filename="dummy.json"',
        }
    )

4. Use HttpResponse to return error info

There are plenty of possible errors that can happen in backend code. Some may be due to incorrect request data, while others may be due to server errors. Regardless of the type of error, you’ll want to return a descriptive response to the client. Django offers many predefined HttpResponse subclasses for that purpose. Some of them are:

  • HttpResponseBadRequest – uses a 400 status code.
  • HttpResponseNotFound – uses a 404 status code.
  • HttpResponseForbidden – uses a 403 status code.
  • HttpResponseNotAllowed – uses a 405 status code.
  • HttpResponseServerError – uses a 500 status code.

Below you can find an example that uses both the HttpResponseBadRequest and HttpResponseNotAllowed classes.

# views.py
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseBadRequest

def bad_request_view(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        if name:
            return HttpResponse('Successfully received %s' % name)
        else:
            return HttpResponseBadRequest('Request data invalid.')
    return HttpResponseNotAllowed(['POST'])

Let me explain the code snippet above. First, we check if the request method is HTTP POST, and in case some other method is used, we return the HttpResponseNotAllowed (405 status code) response. Further, we check if the request body contains the name value. If there is no name value in the request body, we return the HttpResponseBadRequest (400 status code) response, otherwise HttpResponse (200 status code) is returned.