Writing views¶
A view function, or view for short, is a Python function that takes a
web request and returns a web response. This response can be the HTML contents
of a web page, or a redirect, or a 404 error, or an XML document, or an image .
. . or anything, really. The view itself contains whatever arbitrary logic is
necessary to return that response. This code can live anywhere you want, as long
as it’s on your Python path. There’s no other requirement–no “magic,” so to
speak. For the sake of putting the code somewhere, the convention is to
put views in a file called views.py
, placed in your project or
application directory.
A simple view¶
Here’s a view that returns the current date and time, as an HTML document:
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
Let’s step through this code one line at a time:
-
First, we import the class
HttpResponse
from the
django.http
module, along with Python’sdatetime
library. -
Next, we define a function called
current_datetime
. This is the view
function. Each view function takes anHttpRequest
object as its first parameter, which is typically namedrequest
.Note that the name of the view function doesn’t matter; it doesn’t have to
be named in a certain way in order for Django to recognize it. We’re
calling itcurrent_datetime
here, because that name clearly indicates
what it does. -
The view returns an
HttpResponse
object that
contains the generated response. Each view function is responsible for
returning anHttpResponse
object. (There are
exceptions, but we’ll get to those later.)
Django’s Time Zone
Django includes a TIME_ZONE
setting that defaults to
America/Chicago
. This probably isn’t where you live, so you might want
to change it in your settings file.
Mapping URLs to views¶
So, to recap, this view function returns an HTML page that includes the current
date and time. To display this view at a particular URL, you’ll need to create a
URLconf; see URL dispatcher for instructions.
Returning errors¶
Django provides help for returning HTTP error codes. There are subclasses of
HttpResponse
for a number of common HTTP status codes
other than 200 (which means “OK”). You can find the full list of available
subclasses in the request/response
documentation. Return an instance of one of those subclasses instead of a
normal HttpResponse
in order to signify an error. For
example:
from django.http import HttpResponse, HttpResponseNotFound def my_view(request): # ... if foo: return HttpResponseNotFound("<h1>Page not found</h1>") else: return HttpResponse("<h1>Page was found</h1>")
There isn’t a specialized subclass for every possible HTTP response code,
since many of them aren’t going to be that common. However, as documented in
the HttpResponse
documentation, you can also pass the
HTTP status code into the constructor for HttpResponse
to create a return class for any status code you like. For example:
from django.http import HttpResponse def my_view(request): # ... # Return a "created" (201) response code. return HttpResponse(status=201)
Because 404 errors are by far the most common HTTP error, there’s an easier way
to handle those errors.
The Http404
exception¶
-
class
django.http.
Http404
¶
When you return an error such as HttpResponseNotFound
,
you’re responsible for defining the HTML of the resulting error page:
return HttpResponseNotFound("<h1>Page not found</h1>")
For convenience, and because it’s a good idea to have a consistent 404 error page
across your site, Django provides an Http404
exception. If you raise
Http404
at any point in a view function, Django will catch it and return the
standard error page for your application, along with an HTTP error code 404.
Example usage:
from django.http import Http404 from django.shortcuts import render from polls.models import Poll def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404("Poll does not exist") return render(request, "polls/detail.html", {"poll": p})
In order to show customized HTML when Django returns a 404, you can create an
HTML template named 404.html
and place it in the top level of your
template tree. This template will then be served when DEBUG
is set
to False
.
When DEBUG
is True
, you can provide a message to Http404
and
it will appear in the standard 404 debug template. Use these messages for
debugging purposes; they generally aren’t suitable for use in a production 404
template.
Customizing error views¶
The default error views in Django should suffice for most web applications,
but can easily be overridden if you need any custom behavior. Specify the
handlers as seen below in your URLconf (setting them anywhere else will have no
effect).
The page_not_found()
view is overridden by
handler404
:
handler404 = "mysite.views.my_custom_page_not_found_view"
The server_error()
view is overridden by
handler500
:
handler500 = "mysite.views.my_custom_error_view"
The permission_denied()
view is overridden by
handler403
:
handler403 = "mysite.views.my_custom_permission_denied_view"
The bad_request()
view is overridden by
handler400
:
handler400 = "mysite.views.my_custom_bad_request_view"
Testing custom error views¶
To test the response of a custom error handler, raise the appropriate exception
in a test view. For example:
from django.core.exceptions import PermissionDenied from django.http import HttpResponse from django.test import SimpleTestCase, override_settings from django.urls import path def response_error_handler(request, exception=None): return HttpResponse("Error handler content", status=403) def permission_denied_view(request): raise PermissionDenied urlpatterns = [ path("403/", permission_denied_view), ] handler403 = response_error_handler # ROOT_URLCONF must specify the module that contains handler403 = ... @override_settings(ROOT_URLCONF=__name__) class CustomErrorHandlerTests(SimpleTestCase): def test_handler_renders_template_response(self): response = self.client.get("/403/") # Make assertions on the response here. For example: self.assertContains(response, "Error handler content", status_code=403)
Async views¶
As well as being synchronous functions, views can also be asynchronous
(“async”) functions, normally defined using Python’s async def
syntax.
Django will automatically detect these and run them in an async context.
However, you will need to use an async server based on ASGI to get their
performance benefits.
Here’s an example of an async view:
import datetime from django.http import HttpResponse async def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
You can read more about Django’s async support, and how to best use async
views, in Asynchronous support.
When you set debug to False, you don’t have a custom handler, and the status code of the response is 404, the 404.html (if present) in your base template directory is used. To return a response with a 404 status, you can simply return an instance of django.http.HttpResponseNotFound
. The reason you got a 500 is because you raised an error instead of returning a response. So, your test function can be simply modified to this
from django.http import HttpResponseNotFound
def test(request):
return HttpResponseNotFound("hello")
Update:
So it turned out that the reason you are getting a 500 error was not that you raised an exception, but having incorrect function signatures. When I answered this question more than half a year ago I forgot that django catches HTTP404 exception for you. However, the handler view has different signatures than the normal views. The default handler for 404 is defaults.page_not_found(request, exception, template_name='404.html')
, which takes 3 arguments. So your custom handler should actually be
def customhandler404(request, exception, template_name='404.html'):
response = render(request, template_name)
response.status_code = 404
return response
Although, in this case, you may as well just use the default handler.
{% load static %}
<!DOCTYPE html>
<
html
class
=
"no-js"
lang
=
"en"
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
title
>Web Developer</
title
>
<
link
href
=
"{% static 'img/Demo/favicon.png' %}"
rel
=
"shortcut icon"
/>
<
meta
charset
=
"UTF-8"
/>
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
>
<
meta
name
=
"description"
content
=
"Alphaandroid - Creative Agency of web developers"
>
<
meta
name
=
"author"
content
=
"Pavan And Romil"
>
<
meta
name
=
"keywords"
content
=
"Web developer (using coding), Digital Marketing"
/>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1, maximum-scale=1"
>
<
link
rel
=
"stylesheet"
href
=
"{% static 'css/error404/base.css' %}"
>
<
link
rel
=
"stylesheet"
href
=
"{% static 'css/error404/main.css' %}"
>
<
link
rel
=
"stylesheet"
href
=
"{% static 'css/error404/vendor.css' %}"
>
<
script
src
=
"{% static 'js/error404/modernizr.js' %}"
></
script
>
<
link
rel
=
"icon"
type
=
"image/png"
href
=
"{% static 'favicon.png' %}"
>
<
script
>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
})(window,document,'script','dataLayer','GTM-MRJ5QRJ');
</
script
>
</
head
>
<
body
>
height
=
"0"
width
=
"0"
style
=
"display:none;visibility:hidden"
></
iframe
></
noscript
>
{% comment %}
<
header
class
=
"main-header"
>
<
div
class
=
"row"
>
<
div
class
=
"logo"
>
<
a
href
=
"index.html"
>Alpha Android</
a
>
</
div
>
</
div
>
<
a
class
=
"menu-toggle"
href
=
"#"
><
span
>Menu</
span
></
a
>
</
header
>
{% endcomment %}
{% comment %}
<
nav
id
=
"menu-nav-wrap"
>
<
h5
>Site Pages</
h5
>
<
ul
class
=
"nav-list"
>
<
li
><
a
href
=
"/"
title
=
""
>Home</
a
></
li
>
<
li
><
a
href
=
"#"
title
=
""
>About</
a
></
li
>
<
li
><
a
href
=
"#"
title
=
""
>Contact</
a
></
li
>
</
ul
>
<
h5
>Some Text</
h5
>
<
p
>Lorem ipsum Non non Duis adipisicing pariatur eu enim Ut in aliqua dolor esse sed est in sit exercitation eiusmod aliquip consequat.</
p
>
</
nav
>
{% endcomment %}
<
main
id
=
"main-404-content"
class
=
"main-content-particle-js"
>
<
div
class
=
"content-wrap"
>
<
div
class
=
"shadow-overlay"
></
div
>
<
div
class
=
"main-content"
>
<
div
class
=
"row"
>
<
div
class
=
"col-twelve"
>
<
h1
class
=
"kern-this"
>404 Error.</
h1
>
<
p
>
Oooooops! Looks like nothing was found at this location.
Maybe try one of the links below, click on the top menu
or try a search?
</
p
>
{% comment %}
<
div
class
=
"search"
>
<
form
>
<
input
type
=
"text"
id
=
"s"
name
=
"s"
class
=
"search-field"
placeholder
=
"Type and hit enter …"
>
</
form
>
</
div
>
{% endcomment %}
</
div
>
</
div
>
</
div
>
<
footer
>
<
div
class
=
"row"
>
<
div
class
=
"col-seven tab-full social-links pull-right"
>
<
ul
>
<
li
><
a
href
=
"#"
><
i
class
=
"fa fa-facebook"
></
i
></
a
></
li
>
<
li
><
a
href
=
"#"
><
i
class
=
"fa fa-behance"
></
i
></
a
></
li
>
<
li
><
a
href
=
"#"
><
i
class
=
"fa fa-twitter"
></
i
></
a
></
li
>
<
li
><
a
href
=
"#"
><
i
class
=
"fa fa-dribbble"
></
i
></
a
></
li
>
<
li
><
a
href
=
"#"
><
i
class
=
"fa fa-instagram"
></
i
></
a
></
li
>
</
ul
>
</
div
>
<
div
class
=
"col-five tab-full bottom-links"
>
<
ul
class
=
"links"
>
<
li
><
a
href
=
"/"
>Homepage</
a
></
li
>
<
li
><
a
href
=
"/about-us/"
>About Us</
a
></
li
>
{% comment %}
<
li
><
a
href
=
"/contact-us/"
>Contact Us</
a
></
li
>
{% endcomment %}
<
li
><
a
href
=
"mailto:Contact@alphaandroid.com"
>Report Error</
a
></
li
>
</
ul
>
<
div
class
=
"credits"
>
</
div
>
</
div
>
</
div
>
</
footer
>
</
div
>
</
main
>
<
div
id
=
"preloader"
>
<
div
id
=
"loader"
></
div
>
</
div
>
<
script
src
=
"{% static 'js/error404/jquery-2.1.3.min.js' %}"
></
script
>
<
script
src
=
"{% static 'js/error404/plugins.js' %}"
></
script
>
<
script
src
=
"{% static 'js/error404/main.js' %}"
></
script
>
</
body
>
</
html
>
- Home
- Django 1.10 Tutorial
- Showing 404 errors In Django
Last updated on July 27, 2020
Visit a category page which doesn’t exist for example, http://127.0.0.1:8000/category/cat_not_exists/
. You should see DoesNotExist
exception like this:
As there is no such category in the database the URL http://127.0.0.1:8000/blog/category/cat_not_exists/
is completely invalid. In production (i.e when DEBUG=True
), instead of throwing a DoesNotExist
exception Django will show 500 Internal Server Error.
From the point of view of Search Engine Optimization (SEO), it would be much better to show an HTTP 404 error for the non-existent page instead of showing Internal Server Error or DoesNotExist
exception.
The same problem exists in the tag page and the post detail page. Visit any tag or post detail page which doesn’t exist like http://127.0.0.1:8000/tag/tag_not_exists/
or http://127.0.0.1:8000/97712/
and see it yourself.
Showing an HTTP 404 page #
Django provides two ways to show 404 error.
HttpResponseNotFound
classHttp404
exception
Let’s start with HttpResponseNotFound
class.
HttpResponseNotFound class #
The HttpResponseNotFound
class is an extension of HttpResponse
class. It works just like HttpResponse
but instead of returning a 200 status code , it returns 404 (which means page not found). To see how it works, open views.py
and modify the post_detail()
view as follows:
TGDB/django_project/blog/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from django.http import HttpResponse, HttpResponseNotFound #... # view function to display a single post def post_detail(request, pk): try: post = Post.objects.get(pk=pk) except Post.DoesNotExist: return HttpResponseNotFound("Page not found") return render(request, 'blog/post_detail.html', {'post': post}) #... |
Here we are wrapping the code which might throw an exception in the try
and except
block. Now, If get()
method throws a DoesNotExist
exception then instead of displaying an error page, Django will show a 404 error page with "Page not found"
response. Save the changes and visit http://127.0.0.1:8000/99999/
, you should get a response like this:
Http404 exception #
Another way to show a 404 error page is to raise Http404
exception. Notice that unlike HttpResponseNotFound
class, Http404
is an exception. Http404
uses a default 404 page which Django provides. To use it just raise Http404
exception in your code like this:
You can also provide an error message while raising Http404
exception.
raise Http404("Some error message")
Open views.py
file and amend post_detail()
view as follows:
TGDB/django_project/blog/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from django.http import HttpResponse, HttpResponseNotFound, Http404 #... # view function to display a single post def post_detail(request, pk): try: post = Post.objects.get(pk=pk) except Post.DoesNotExist: raise Http404("Post not found") return render(request, 'blog/post_detail.html', {'post': post}) #... |
Save the file and visit http://127.0.0.1:8000/blog/99999/
, you will see the following 404 error page.
We are currently in development mode. In production (i.e when DEBUG=False
) Django will show 404 page which looks like this:
The get_object_or_404() method #
Most of the time our views function goes like this:
- Code try and except block.
- Query the database in the try block.
- If an exception is thrown, catch the exception in the except block and show a 404 page.
This pattern is so common that Django a provides a shortcurt method called get_object_or_404()
. Here is the syntax of get_object_or_404()
.
Syntax: get_object_or_404(klass, **kwargs)
The klass
can be a model, a manager or a Queryset
object.
The **kwargs
represents all keyword arguments as well as lookup parameters that we have been using with the get()
and filter()
method.
On success, it returns a single object of the given model, if it can’t find any records then it raises a Http404
exception.
Internally this method calls get()
method of objects manager, so you must always use this method to get a single record.
To use get_object_or_404()
first import it from django.shortcuts
using the following code.
from django.shortcuts import get_object_or_404
The following examples shows how to use get_object_or_404()
method with models, queryset and managers. It also shows that when a matching record is not found, get_object_or_404()
raises a Http404
exception.
Example 1: where klass
is model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> >>> from django.shortcuts import get_object_or_404 >>> from blog.models import Category, Post, Tag, Author >>> post = get_object_or_404(Post, pk=1) >>> >>> post <Post: Post 1> >>> >>> >>> post = get_object_or_404(Post, pk=990) Traceback (most recent call last): ... django.http.response.Http404: No Post matches the given query. >>> >>> |
The above code is equivalent to:
>>> >>> try: ... post = Post.objects.get(pk=1) ... except Post.DoesNotExist: ... raise Http404("Post not found") ... >>> |
Example 2: where klass
is queryset
>>> >>> queryset = Post.objects.filter(title__contains="Post 1") >>> queryset <QuerySet [<Post: Post 1>]> >>> >>> post = get_object_or_404(queryset, pk=1) >>> >>> post <Post: Post 1> |
>>> >>> >>> post = get_object_or_404(queryset, pk=10) # get_object_or_404() will now raise an exception Traceback (most recent call last): ... raise Http404('No %s matches the given query.' % queryset.model._meta.object _name) django.http.response.Http404: No Post matches the given query. >>> >>> |
Example 3: where klass
is manager
>>> >>> c = Category.objects.get(name='java') >>> c <Category: java> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
>>> >>> post = get_object_or_404(c.post_set, title__contains="Post 2") >>> >>> post <Post: Post 2> >>> >>> >>> post = get_object_or_404(c.post_set, title__contains="tagged") Traceback (most recent call last): ... raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) django.http.response.Http404: No Post matches the given query. >>> >>> |
Let’s update our post_detail()
view to use get_object_or_404()
method.
TGDB/django_project/blog/views.py
#... from django.shortcuts import render, get_object_or_404 #... # view function to display a single post def post_detail(request, pk): post = get_object_or_404(Post, pk=pk) return render(request, 'blog/post_detail.html', {'post': post}) #... |
The get_list_or_404() method #
The get_list_or_404()
works just like get_object_or_404()
method, but instead of returning a single result, it returns a queryset object. If no matching results found, it raises a Http404
exception.
Open views.py
file and update post_by_category()
and post_by_tag()
view functions to use get_list_or_404()
method as follows:
TGDB/django_project/blog/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#... from django.shortcuts import render, get_object_or_404, get_list_or_404 #... # view function to display post by category def post_by_category(request, category_slug): category = get_object_or_404(Category, slug=category_slug) posts = get_list_or_404(Post, category=category) context = { 'category': category, 'posts': posts } return render(request, 'blog/post_by_category.html', context) # view function to display post by tag def post_by_tag(request, tag_slug): tag = get_object_or_404(Tag, slug=tag_slug) posts = get_list_or_404(Post, tags=tag) context = { 'tag': tag, 'posts': posts, } return render(request, 'blog/post_by_tag.html', context ) |
After updating views, visit any non-existent category page, tag page or post detail page, you should get a proper HTTP 404 error.
Creating SEO friendly URLs #
As the situation stands, our post detail page URLs looks like http://127.0.0.1:8000/6/
. Although it is working fine, the problem is that by looking at the URL nobody can tell what the post is about. It would be good to create URLs which describes something about the post.
For our blog, we will create a URL pattern like the following:
http://example.com/post-pk/post-slug
Let’s implement this URL pattern.
Open urls.py
in the blog app and amend post_detail
URL pattern as follows:
TGDB/django_project/blog/urls.py
#... urlpatterns = [ url(r'^category/(?P<category_slug>[w-]+)/$', views.post_by_category, name='post_by_category'), url(r'^tag/(?P<tag_slug>[w-]+)/$', views.post_by_tag, name='post_by_tag'), url(r'^(?P<pk>d+)/(?P<post_slug>[wd-]+)$', views.post_detail, name='post_detail'), url(r'^$', views.post_list, name='post_list'), ] |
Update post_detail()
view function to accept another parameter called post_slug
as follows:
TGDB/django_project/blog/views.py
#... # view function to display a single post def post_detail(request, pk, post_slug): post = get_object_or_404(Post, pk=pk) return render(request, 'blog/post_detail.html', {'post': post}) #... |
At last, we need to modify the get_absolute_url()
method of the Post
model. Open models.py
and update get_absolute_url()
method of Post
model as follows:
TGDB/django_project/blog/models.py
#... class Post(models.Model): #... def get_absolute_url(self): return reverse('post_detail', args=[self.id, self.slug]) #... |
As we are using get_absolute_url()
method to generate links to post detail page in our templates, we don’t need to modify anything else. All templates will pick the changes automatically.
To view the updated URL visit http://127.0.0.1:8000/
and click on any post detail page.
Listing posts in reverse chronological order #
Currently, all pages of our site display posts in the order in which they are inserted into the database. For usability purpose, it would be much better to display posts in reverse chronological order i.e latest first, oldest last.
This change would be very simple. Open views.py
in the blog app and update post_list()
, post_by_category()
and post_by_tag()
views as follows:
TGDB/django_project/blog/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#... # view function to display a list of posts def post_list(request): posts = Post.objects.order_by("-id").all() return render(request, 'blog/post_list.html', {'posts': posts}) # view function to display a single post def post_detail(request, pk, post_slug): post = get_object_or_404(Post, pk=pk) return render(request, 'blog/post_detail.html', {'post': post}) # view function to display post by category def post_by_category(request, category): category = get_object_or_404(Category, slug=category_slug) posts = get_list_or_404(Post.objects.order_by("-id"), category=category) context = { 'category': category, 'posts': posts } return render(request, 'blog/post_by_category.html', context) # view function to display post by tag def post_by_tag(request, tag): tag = get_object_or_404(Tag, slug=tag_slug) posts = get_list_or_404(Post.objects.order_by("-id"), tags=tag) context = { 'tag': tag, 'posts': posts } return render(request, 'blog/post_by_tag.html', context ) |
From now on, all the pages of our blog will display posts in reverse chronological order.
Note: To checkout this version of the repository type git checkout 18a
.
Whenever one tries to visit a link that doesn’t exist on a website, it gives a 404 Error, that this page is not found. Similarly, there are more error codes such as 500, 403, etc. Django has some default functions to for handle HTTP errors. Let’s explore them one-by-one.
Built-in Error Views in Django –
404 view (page not found) –
Normally this view is used by to render basic 404 template when requested URL is not available on the server. This situation happens by default Django raises django.views.defaults.page_not_found() view and render default404 error template. You can customize it by adding custom 404.html page inside templates folder.
500 view (server error) –
This view is used when the server has been crashed or didn’t respond to anything. In this case Django has default function django.views.defaults.server_error() to render server error for this view. You can also customize it by adding your 500.html page inside the templates folder.
403 view (Forbidden) –
When user does not have permission to view particular page but he/she requests to view that page. In that case 403 view comes into play. It says page is forbidden and will not show page to that user. For that Django has django.views.defaults.permission_denied() function to render forbidden template. It maintains your privacy and only permitted users can access certain pages. You can also customize it by adding your 403.html page inside the templates folder.
Suppose you have an ecommerce website and you only want authenticated merchants to list products. Buyers and normal users can’t list their products. You can add this functionality in Django like this:
from django.core.exceptions import PermissionDenied def upload(request, pk): if not request.user.is_merchant: raise PermissionDenied # your code here.....
400 view (Bad Request):
The 400 view or Bad Request view is used by Django when someone try to access confidential page of your site which may lead your site to be hacked or leak confidential data. So, you don’t want anyone to access that page. Django has django.views.defaults.bad_request() to raise 400 view for any kind of SuspiciousOperation. This prevents your site from Bad peoples.
Customize Built-in Error Views in Django –
Now, let’s see how to customize these error views. First of all you need to go into settings.py and set Debug=False.
DEBUG = False ALLOWED_HOSTS = ['localhost', '127.0.0.1']
Make folder inside the project and name it anything, here I am giving name ‘templates‘ to that folder. Now go to settings.py and set templates directory.
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
Now, inside the templates directory you can create html files ‘404.html’, ‘500.html’, ‘403.html’, ‘400.html’, etc. After creating these pages show your HTML skills and customize pages by yourself. Add your app name into settings.py.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'jquery', 'geeks' ]
Add the handler method to urls.py
handler404 = 'myappname.views.error_404' handler500 = 'myappname.views.error_500' handler403 = 'myappname.views.error_403' handler400 = 'myappname.views.error_400'
Now set logic to show these pages in views.py
from django.shortcuts import render def error_404(request, exception): return render(request,'404.html') def error_500(request, exception): return render(request,'500.html', data) def error_403(request, exception): return render(request,'403.html') def error_400(request, exception): return render(request,'400.html', data)
Now, you are all set to run the server and see these error handling pages made by you.
To run server: python manage.py runserver
Last Updated :
01 Nov, 2020
Like Article
Save Article