Lecture 4 Django Part 2
Lecture 4 Django Part 2
Lecture 4
Django – Part 2
Outline
• Introduction
• Web Applications
• HTTP
• Django
Routes
Templates
Conditionals
Styling
Tasks
Forms
Django Forms
Sessions
Django - Forms
• Continuing with the tasks example, let’s now add the ability to add tasks to the list.
• Make sure to add another path to urls.py:
• Now, we’ll create our add.html file, which is fairly similar to index.html, except that in the body we’ll include a form
rather than a list:
Django - Forms
• However, what we’ve just done isn’t necessarily the best design, as we’ve just repeated the bulk of that HTML in two
different files.
• Django’s templating language gives us a way to eliminate this poor design: template inheritance.
• This allows us to create a layout.html file that will contain the general structure of our page:
layout.html
Django - Forms
• Notice that we’ve again used {%...%} to denote some sort of non-HTML logic, and in this case, we’re telling Django
to fill this “block” with some text from another file.
• Now, we can alter our other two HTML files to look like:
index.html add.html
Django - Forms
• Notice how we can now get rid of much of the repeated code by extending our layout file.
• Now, our index page remains the same, and we now have an add page as well:
Django - Forms
• Next, it’s not ideal to have to type “/add” in the URL any time we want to add a new task, so we’ll probably want to
add some links between pages.
• Instead of hard-coding links though, we can now use the name variable we assigned to each path in urls.py, and
create a link that looks like this (in index.html):
• where ‘add’ is the name of that path. We can do a similar thing in our add.html:
Django - Forms
• This could potentially create a problem though, as we have a few routes named index throughout our different
apps. We can solve this by going into each of our app’s urls.py file, and adding an app_name variable, so that the
files now look something like this:
• We can then change our links from (index and add) to tasks:index and tasks:add.
Django - Forms
• Now, let’s work on making sure the form actually does something when the user submits it. We can do this by
adding an action to the form we have created in add.html:
• This means that once the form is submitted, we will be routed back to the add URL.
• Here we’ve specified that we’ll be using a post method rather than a get method, which is typically what we’ll use
any time a form could alter the state of that web page.
• We need to add a bit more to this form now, because Django requires a token to prevent Cross-Site Request
Forgery (CSRF) Attack.
• This is an attack where a malicious user attempts to send a request to your server from somewhere other than your
site.
• This could be a really big problem for some websites.
Django - Forms
• Say, for example, that a banking website has a form for one user to transfer money to another one. It would be
catastrophic if someone could submit a transfer from outside of the bank’s website!
• To solve this problem, when Django sends a response rendering a template, it also provides a CSRF token that is
unique with each new session on the site. Then, when a request is submitted, Django checks to make sure the
CSRF token associated with the request matches one that it has recently provided.
• Therefore, if a malicious user on another site attempted to submit a request, they would be blocked due to an invalid
CSRF token.
• This CSRF validation is built into the Django Middleware framework, which can intervene in the request-response
processing of a Django app.
• We won’t go into any more detail about Middleware in this course, but do look at the documentation if interested!
Django - Forms
• To incorporate this technology into our code, we must add a line to our form in add.html.
• This line adds a hidden input field with the CSRF token provided by Django, such that when we reload the page, it
looks as though nothing has changed. However, if we inspect element, we’ll notice that a new input field has been
added:
Django - Forms
• While we can create forms by writing raw HTML as we’ve just done, Django provides an even easier way to collect
information from a user: Django Forms.
• In order to use this method, we’ll add the following to the top of views.py to import the forms module:
• Now, we can create a new form within views.py by creating a Python class called NewTaskForm:
Django - Forms
• Now that we’ve created a NewTaskForm class, we can include it in the context while rendering the add page:
• Now, within add.html, we can replace our input field with the form we just created:
Django - Forms
• There are several advantages to using the forms module rather than manually writing an HTML form:
If we want to add new fields to the form, we can simply add them in views.py without typing
additional HTML.
Django automatically performs client-side validation, or validation local to the user’s machine.
meaning it will not allow a user to submit their form if it is incomplete.
Django provides simple server-side validation, or validation that occurs once form data has
reached the server.
In the next lecture, we’ll begin using models to store information, and Django makes it very
simple to create a form based on a model.
Django - Forms
• Now that we have a form set up, let’s work on what happens when a user clicks the submit button:
When a user navigates to the add page by clicking a link or typing in the URL, they submit a GET
request to the server, which we’ve already handled in our add function.
When a user submits a form though, they send a POST request to the server, which at the
moment is not handled in the add function.
We can handle a POST method by adding a condition based on the request argument our
function takes in.
The comments in the code (Next Slide) explain the purpose of each line.
Django - Forms
• form.cleaned_data returns a dictionary of validated form input fields and their values.
• form.data returns a dictionary of un-validated form input fields and their values.
Example:
• Cleaned data
{'username': 'xyz', 'password': 'shinchan’}
• Uncleaned or raw data
• <tr><th><label for="id_username">Username:</label></th>
<td><input type="text" name="username" value="xyz" required id="id_username"></td></tr>
<tr><th><label for="id_password">Password:</label></th><td><input type="password"
name="password" required id="id_password"></td></tr>
• Why the method from before is called reverse? It takes an input of a url name and gives the actual
url, which is reverse to having a url first and then give it a name.
Django - Sessions
• At this point, we’ve successfully built an application that allows us to add tasks to a growing list.
However, it may be a problem that we store these tasks as a global variable, as it means that all of
the users who visit the page see the exact same list.
• In order to solve this problem we’re going to employ a tool known as sessions.
• Sessions are a way to store unique data on the server side for each new visit to a website.
• To use sessions in our application, we’ll first delete our global tasks variable, then alter our index
function, and finally make sure that anywhere else we had used the variable tasks, we replace it with
request.session["tasks"]
Django - Sessions
Django - Sessions
• Finally, before Django will be able to store this data, we must run python3 manage.py migrate in the
terminal.
• Next week we’ll talk more about what a migration is, but for now just know that the above command
allows us to store sessions.
• That’s all for this lecture! Next time we’ll be working on using Django to store, access, and manipulate
data.