You want to use HTTP handling directly in Django views to output HTTP error pages, HTTP redirects, HTTP content types (e.g. text/plain, text/xml) and HTTP status codes ('HTTP 200 for "OK"','HTTP 404 for "NOT FOUND"').
content_type arguments with the
django.shortcuts.render method to specify an HTTP status code and HTTP content type, respectively. To trigger an HTTP 500 (INTERAL SERVER ERROR) response do
raise Exception in a view. To trigger an HTTP 404 (NOT FOUND) response do
raise django.http.Http404. To trigger an HTTP 400 (BAD REQUEST) response do
raise django.core.exceptions.SuspiciousOperation. To trigger an HTTP 403 (FORBIDDEN) response do
You can customize the pages for HTTP 404, HTTP 500, HTTP 400 and HTTP 403 responses creating templates called
403.html, respectively. Custom templates must be placed in a folder defined in the
DIRS list of the
TEMPLATES variable. You can also override the built-in view methods for HTTP 404, HTTP 500, HTTP 400 and HTTP 403 responses defining custom view methods in the variables
handler403. The variables for custom view methods must be defined in
To do an HTTP redirect you can use
django.http.HttpResponseRedirect(). To trigger an HTTP 304 (NOT MODIFIED) response use
django.http.HttpResponseNotModified(). To trigger an HTTP 400 (BAD REQUEST) response with in-line content use
django.http.HttpResponseBadRequest(). To trigger an HTTP 404 (NOT FOUND) response with in-line content use
django.http.HttpResponseNotFound(). To trigger an HTTP 403 (FORBIDDEN) response with in-line content use
django.http.HttpResponseForbidden(). To trigger an HTTP 405 (METHOD NOT ALLOWED) response with in-line content use
django.http.HttpResponseNotAllowed(). To trigger an HTTP 410 (GONE) response with in-line content use
django.http.HttpResponseGone(). To trigger an HTTP 500 (INTERNAL SERVER ERROR) response with in-line content use
To trigger a response with in-line content using any HTTP status code and HTTP content type use the generic method
django.http.HttpResponse(). To trigger a response with in-line content serialized as JSON use
Browsers set HTTP headers in requests to tell applications to take into account certain characteristics for processing. Similarly, applications set HTTP headers in responses to tell browsers to take into account certain characteristics for the content being sent out. Among the most important HTTP headers set by applications like Django are
Status HTTP Header is a three digit code number to indicate the response status for a given request. Examples of
Status values are
200 which is the standard response for successful HTTP requests and
404 which is used to indicate a requested resource could not be found. The
Content-Type HTTP Header is a MIME(Multipurpose Internet Mail Extensions) type string to indicate the type of content in a response. Examples of
Content-Type values are
text/html which is the standard for an HTML content response and
image/gif which is used to indicate a response is a GIF image.
By default and unless there's an exception (i.e. an error), all Django view methods that use
django.shortcuts.render to return a response are set with the HTTP
Status value of
200 and the HTTP
text/html. Although these default values are the most common, sometimes it's necessary to alter these values.
Statuscode in Django
Adding HTTP handling to the
render method in
django.shortcuts is as simple as providing the additional arguments
content_type. Listing 1 illustrates various examples of this process.
django.shortcuts.renderwith modified HTTP
The first example in listing 1 is designed to return a response with plain text content. Notice the
request arguments with the exception of the
content_type are identical to previous recipes: the
request object, a template to generate the response and a data dictionary to fill values in the template.
The second and third examples in listing 1 set the HTTP
Status code to
500. Because the HTTP
404 code is used for resources that are not found, the
render method uses a special template for this purpose. Similarly, because the HTTP
500 code is used to indicate an error, the
render method uses a special template for this purpose. Note that Django has built-in shortcuts and templates to deal with HTTP
500 that are described in the next section and that you can use instead of the examples in listing 1.
The fourth and last example in listing 1 is designed to return a response with JSON content. The HTTP
application/json is a common requirement when requests are made via AJAX. Finally, it's worth mentioning that can you can specify both the
status arguments if required.
404 (Not Found),
500 (Internal Server Error),
400 (Bad Request)and
Django has special shortcuts and built-in templates for certain HTTP
Status codes that are very common. All that's required to use these shortcuts is to trigger an exception in a Django view. Table 1 illustrates the different shortcuts to trigger certain HTTP statuses.
|HTTP status code||Python code sample|
|404 (Not Found)|
|500 (Internal Server Error)|
|400 (Bad Request)|
|Django automatically handles not found pages raising HTTP 404 and unhandled exceptions raising HTTP 500|
The exceptions in table 1 are meant to be used explicitly in Django views when developers know end users should get them. However, Django automatically triggers an HTTP 404 (Not Found) exception when a page is not found or triggers an HTTP 500 (Internal Server Error) exception when an unhandled exception is thrown in a view.
As you can see in the examples in table 1, the shortcut syntax is straightforward. For example, you can make evaluations in a Django view like
if article_id < 100: or
if unpayed_subscription: and based on the result throw exceptions from table 1 so end users get the proper HTTP status response.
So what is the actual content sent in a response besides the HTTP status when an exception from table 1 is triggered ? The default for HTTP
400 (Bad Request) and HTTP
403 (Forbidden) is a single line HTML page that says "
Bad Request (400)" and "
403 Forbidden", respectively. For HTTP
404 (Not Found) and HTTP
500 (Internal Server Error), it depends on the
DEBUG value in
If a Django project has
404 (Not Found) generates a page with the available URLs -- as illustrated in figure 1 -- and HTTP
500 (Internal Server Error) generates a page with the detailed error -- as illustrated in figure 2. If a Django project has
404 (Not Found) generates a single line HTML page that says "
Not Found. The requested URL <url_location> was not found on this server." and HTTP
500 (Internal Server Error) generates a single line HTML page that says "
A server error occurred. Please contact the administrator.".
It's also possible to override the default response for all the previous HTTP codes using a custom template. To use a custom response template, you need to create a template with the desired HTTP code and
.html extension. For example, for HTTP
403 you would create the
403.html template and for HTTP
500 you would create the
500.html template. All these custom HTTP response templates need to be placed in a folder defined in the
DIRS list of the
TEMPLATES variable so Django finds them before it uses the default HTTP responses.
On certain occasions, simply customizing the HTTP response template may not be enough. For example, you may need to pass a custom data structure to use in the template. Under these circumstances you need to customize the built-in Django HTTP view methods themselves because there's no other way to get custom data into a template. To customize the built-in Django HTTP view methods you need to use special handlers in
urls.py. Listing 2 illustrates the
urls.py file with custom handlers for Django's built-in HTTP view methods.
As you can see in listing 2, there are a series of variables in
urls.py right above the standard
urlpatterns variable. Each variable in listing 2 represents an HTTP handler, with its value corresponding to a custom Django view to process requests. For example,
handler400 indicates that all HTTP 400 requests should be handled by the Django view method
coffeehouse.utils.views.bad_request instead of the default
django.views.defaults.bad_request. The same approach is taken for HTTP 403 requests using
handler403, HTTP 404 requests using
handler404 and HTTP 500 requests using
As to the actual structure of the custom Django view methods, they are identical to any other Django view method. Listing 3 show the structure of the custom view methods used in listing 2.
As you can see in listing 3, we use the same
render method from
django.shortcuts to build the custom HTTP view methods. The methods point to a template named by the HTTP status code, use a custom data dictionary that can be accessible on the template and use the
status argument to indicate the HTTP status code.
Statuscodes and responses that don't require templates
All the previous samples assumed the responses with an HTTP status code had to return content from a template. However, there can be times when using a template to output a response can be unnecessary, for example, you might want a one line response that says "Nothing to see here". Other times it makes no sense for an HTTP status code to use a template, such is the case for
HTTP 301 (Permanent Redirect) or
HTTP 302 (Redirect) where the response should be a redirection URL.
Table 2 illustrates the different shortcuts to trigger HTTP redirects.
|HTTP status code||Python code sample|
|301 (Permanent Redirect)|
Both samples in table 2 redirect to an application's home page (i.e."
/"). However, you could also set the redirection to any application URL or even a full URL on a different domain (e.g.
In addition to the HTTP redirection shortcuts, Django also offers a series of shortcuts for common HTTP status codes where you can add in-line responses instead of relying on a template. These shortcuts can also use the
content_type argument to indicate the type of content in a response. Table 3 illustrates the various other shortcuts for HTTP status codes with in-line content responses.
|HTTP status code||Python code sample|
|304 (NOT MODIFIED)|
|400 (BAD REQUEST)|
|404 (NOT FOUND)|
|405 (METHOD NOT ALLOWED)|
|500 (INTERNAL SERVER ERROR)|
|In-line response with any HTTP status code (Defaults to HTTP 200)|
|In-line response that serializes data to JSON (Defaults to HTTP 200 and content type |
|1The HTTP 304 status code indicates a 'Not Modified' response, so you can't send content in the response, it should always be empty.|
As you can see in the samples in table 3, you can provide an in-line content response, as well as the
content_type argument if the content is something other than
HttpResponse method in the second to last line in table 3 is a generic method for in-line content responses. The
HttpResponse method can specify any HTTP status code using the
status argument, the content type using the
content_type argument -- similar to the
render method in listing 1 -- or any other HTTP header (e.g.
HttpResponse method is helpful to create responses for HTTP status codes that don't have direct shortcut methods (e.g. HTTP 408 [Request Timeout], HTTP 429 [Too Many Requests]) or to inclusively harness a template to generate inline responses as illustrated in listing 4.
HTTPResponse object in listing 4 is generated with a
text/csv content type to advise the requesting party (e.g. browser) that it's about to receive CSV content. Next, the
Content-Disposition header also tells the requesting party (e.g. browser) to attempt to download the content as a file named
Users_%s.csv where the
%s is substituted with the current server date.
Next, using the
loader module we use the
get_template method to load the template
users_csvexport.html that will have a CSV like structure with data placeholders. Then we create a
Context object to hold the data that will fill the template, in this case it's just a single variable named
users. Next, we call the template's
render method with the context object in order to fill in the template's data placeholders with the data. Finally, the rendered template is written to the
response object via the
write method and the
response object is returned.
And finally, turning our attention back to table 3 with the Django shortcuts, the
JsonResponse method is used to transform an in-line response into a JSON format. Because this method converts the payload to a JSON data structure, it also automatically sets the