In this tutorial, we are going to explain how to create and maintain a user session by using cookies. A cookie is one of the most common ways to track a user on the internet. Cookie is a file using which you can store the information in a user's
browser and once it is done, you can access it when you need to communicate with a user or to manage a user's session.
You can even specify the duration for which this cookie file is going exist before it gets deleted by the browser.
So let us create a Django project to explain you how to maintain a user session with cookies using Django Framework. To elaborate this, let us create a new Django project.
Creating a Django project
To create a directory for our project, we need to open the Command Prompt and type in the command -
django-admin startproject django_with_cookie
dhago-admin is a management utility for Django Framework, using which we could create a new project and much more.
startproject is a command to start a new Django project.
django_with_cookie is the name of our Django project and also the name of our project directory created in the current directory.
The startproject command gives us a sub-directory and files
Executing the startproject command has not only created a project directory named django_with_cookie, but has also created a file manage.py and another sub-directory
with the same name as the project directory, which also contains some Python files -
django_with_cookie is the root directory of our Django project, also known as the container of our project.
manage.py is a command-line utility which allows us to interact with Django project in various ways.
django_with_cookie sub-directory is actually a Python package for our project. We can import this package(a group of modules) and its contents just like we import any general Python package/module and its contents.
__init__.py is a file which allows our sub-directory django_with_cookie to be treated as a Python package.
settings.py is a file used for setting the configurations for our Django project.
urls.py is a file used to specify the URL declarations for our Django project, also known as a a table of contents.
wsgi.py is a file used as an entry-point for WSGI web-servers to serve your project.
Starting the development server
After creating the project directory and the files required to run our Django project, it is time to execute the Django Development Server. To do this,
we will have to open the command prompt, change the current directory to the root directory of our Django project and execute the following command.
python manage.py runserver
Executing the above mentioned command at the command prompt will trigger the Django Development Server in action, as you can see in the picture below.
E:\Django Projects\django_with_cookie>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 16 unapplied migration(s). Your project may not work properly until you
apply the migrations for app(s): admin, auth, contenttypes.
Run 'python manage.py migrate' to apply them.
September 19, 2019 - 17:37:35
Django version 2.2.1, using settings 'django_with_cookie.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Now that you have successfully started the Django development server, it is time to visit the http://127.0.0.1:8000/ link and you will see a webpage displaying a congratulatory message, as shown below.
Note: The runserver command runs the Django development server at the port 8000.
Enabling Sessions
To implement cookie based sessions, open the settings.py file in the project folder django_with_cookies and set the SESSION_ENGINE setting to "django.contrib.sessions.backends.signed_cookies", as shown below.
Sessions are maintained through a middleware, which is specified in settings.py file.
To maintain a session with cookie using Django Framework, make sure that
MIDDLEWARE setting in settings.py contains the 'django.contrib.sessions.middleware.SessionMiddleware'.
Note: The SessionMiddleware provides session support. The default settings.py created by django-admin startproject command has SessionMiddleware activated.
Please Note:
By default, Django stores the session information in the database by using the model django.contrib.sessions, which is specified in the file settings.py against the INSTALLED_APP setting.
As we want to store the session information in the cookie and not a database, hence, we need to add a # in front of django.contrib.sessions against the INSTALLED_APPS setting in the settings.py file, which will disable the storing of session information in a database.
Creating an app in our project
A project may contain one or multiple applications. As we have already created a project, now let us create a welcome application in it which welcomes the user. This application will be created right under our root - project directory django_with_cookie.
To create an application, we have to open another window command prompt, change the current directory to the root directory of our Django project and execute the following command -
python manage.py startapp cookies
The command startapp in combination with manage.py utility is used to create an app of a project, using which we have created an app named - cookies.
Executing the startapp command has not only created an application directory named cookies in the root - project directory, but has also created the following set of Python files -
Next, we are going to create an HTML template file within our application folder cookies, we will name this file template.htm.
In this HTML template file, we will define an HTML form with its basic elements:
An action attribute, used to specify the form handler.
An HTTP method, used to submit the form data. This method could be POST or GET.
template.htm
<html>
<head><title>Django Framework with cookies - Decodejava.com</title></head>
<body>
Welcome! Please fill the form below:
<form action="form_submit/" method="post">
{% csrf_token %}
{{ form|linebreaks }}
<input type="submit" value="OK">
</form>
</body>
</html>
This HTML template file contains two parts:
In this HTML template file, we have specified a variable - form within the double curly brackets {{ }}.
This form variable allow us to access the form fields specified in the cookies.py(going to create it next) and dynamically insert them in this HTML template file.
The static part, such as a submit button which actually sends the form data.
Note:
We have used the form variable with the linebreaks filter, which installs an HTML linebreak <br/> in the HTML template file, after displaying each form field specified the cookies.py.
Creating the Form class - cookies.py
Up next, we are going to create a form class named NameForm by extending the in-built Form class. This file will be created within the application i.e. cookies folder.
cookies.py
from django import forms
class NameForm(forms.Form):
first_name = Form.CharField(label='Enter your name', max_length=100)
age = Form.IntegerField(label='Enter your age ')
city = forms.CharField(label='Enter your city')
email = Form.EmailField(label='Enter your email')
married = Form.BooleanField(label='Are you married?', required= False)
As you can see in the form class NameForm, we have specified its four fields:
The field name first_name is based on the Field class CharField, for char input.
The field name age is based on the Field class IntegerField, for integer input.
The field name city is based on the Field class CharField, for chat input.
The field name email is based on the Field class EmailField, for email input.
The field name married is based on the Field class BooleanField, for boolean input.
Creating the view - view.py
Once we have created the HTML template file in the application, we will also need to create a view which comprises of one of more view functions.
A view function is simply a Python function which takes an HttpRequest from the HTML template file and returns an HttpResponse with the values of the variables specified and requested by the HTML template file, such as - form variable specified within the HTML template file.
Note: This view functions are defined in the file view.py, which is already created and stored in our application directory, cookies. Let us just copy and paste the following code in view.py.
view.py
from django.shortcuts import render
from django.http import HttpResponse
from .cookies import NameForm
# This view function is used when the form is requested for the first time to display it to the user
def get_form(request):
form = NameForm()
return render(request, 'template_ex.htm', {'form': form})
# This view function is used to save the items in a cookie and to read the items back from the saved cookie
def save_read_cookie(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# This will set a test cookie in the user's browser
request.session.set_test_cookie()
# This will delete this test cookie when the user's browser is closed.
request.session.set_expiry(0)
# check whether the form data is valid
if form.is_valid():
# Saving number of items in a cookie
request.session['first_name']= form.cleaned_data.get("first_name")
request.session['age']= form.cleaned_data.get("age")
request.session['city']= form.cleaned_data.get("city")
request.session['country']= form.cleaned_data.get("country")
request.session['email']= form.cleaned_data.get("email")
request.session['married']= form.cleaned_data.get("married")
# Reading each item in the saved cookie and storing it in a dictionary
dic = ({ 'f_n' : request.session['first_name'],
'age' : request.session['age'],
'city' : request.session['city'],
'country' : request.session['country'],
'email' : request.session['email'],
'married' : request.session['married'] })
# Redirect to a new URL and passing it the dictionary of items in a cookie
return render(request, 'welcome.htm', dic)
# This view function will delete the saved cookie from user's browser
def delete_cookies(request):
# Checking if there is test cookie created and stored in user's browser
if (request.session.test_cookie_worked()):
print("Yes, there was a test cookie in your browser")
# This will delete the cookie when the browser is closed.
request.session.flush()
return HttpResponse('You have been logged out!')
In this view.py file, we have imported the render function from the django.shortcuts module and have defined three view functions:
View Functions
Description
get_form
This view function is used to display the form to the user for the first time.
save_read_cookie
This view function is used to process the form data sent by the user, create a test cookie by calling set_test_cookie() method on session object and save the items in a cookie and to read the items back from the saved cookie.
delete_cookie
This view function checks if there is a test cookie already saved in the user's browser by calling test_cookie_worked() method on the session object and if it there is one then it deletes the saved cookie from the user's browser by calling the flush() method.
The view function - get_form takes an HttpRequest object in its parameter and we have named this parameter - request.
Note:Each view function takes an HttpRequest object in its first parameter and it could named anything but its typically named - request.
In this view function, we have simply created an object of NameForm Form class.
To initiate the process of rendering, we call the render() method, which replaces the form variable declared in HTML template file with the values of form fields specified in the NameForm class.
The render() method requires three parameters passed to it:
Request - An incoming request.
Path to the HTML template - This is a path relative to the path specified in settings.py file.
Context - Since, Django 1.8+ version, the render() method takes a Context, which should be represented by a dictionary of variables needed in the template.
On call, the render() method renders the request from template_ex.htm page and returns an HttpResponse object with the rendered form fields.
The save_read_cookies view function processes the form data submitted by the user, when the form is sent by using the HTTP POST method.
In the save_read_cookies view function, we have called the is_valid() method on the Form instance(referring to NameForm), which runs the validation checks on all the form fields specified in the NameForm class.
If the form data send by the user is valid then we have set a test cookie in the user's browser by calling the set_test_cookie() method on the session attribute of type backends.base.SessionBase class.
Note:
As the SessionMiddleware is activated(as shown in Enabling Session Section), each HttpRequest object – the first argument to any Django view function – will have a session attribute.
Next, we have read the saved items of the cookie and have stored the values of these items in a dictionary object, referenced by dic.
Finally, we have called the render() method to render the welcome.htm page and have passed it the dictionary object.
If the form data is invalid then we have called the render() method to render the error.htm page
Creating the welcome.htm webpage
Once a user has correctly filled the form and have submitted it, a welcome.htm webpage is displayed to the user, displaying the profile created for the user after a successful login. This webpage will be stored in the folder of our application, cookies.
thanks.htm
<html>
<head><title>Django With Forms - Decodejava.com</title></head>
<body>
<b>Your Profile:</b>
<br/>
<br/>
Welcome {{ f_n }}, <br/>
Your city = {{ city }} <br/>
Your country = {{ country }}<br/>
Your age = {{ age }}<br/>
Your email = {{ email }} <br/>
Are you married? = {{ married }} <br/>
<br/>
You are logged in!
Thank you for submitting the form.
<br/>
<a href="logout/">Log out?</a>
</body>
</html>
Mapping URL to view
After creating the view functions of an application, we need to specify the mapping between a URL and each view function in a file named - urls.py. The file urls.py is simply coded in Python and we will have to create the urls.py file in the folder of our application, cookies.
The use of mapping a URL to the view function is, when this URL is requested by the user, its mapped view function is executed and a response is returned.
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.get_form),
path('form_submit/', views.save_read_cookies),
path('form_submit/logout/', views.delete_cookies),
]
As you can see in the file urls.py, we have imported the path() function from the module django.urls.
The path() function has been passed the two must arguments -
An empty string to specify the URL pattern, specified by ' ', this empty string will be matched to the view function - get_form.
A string 'form_submit/' will be matched to the view function - save_read_cookies, defined in the application's views.py.
A string 'form_submit/logout' will be matched to the view function - delete_cookies, defined in the application's views.py.
Note:
This URL pattern specified in the application's urls.py file gets added to another URL pattern, specified in the project's urls.py file(we are going to create it next), and the combined path will be matched to the view functions defined in the application's views.py.
Pointing the project URL to application URL
Next, we are going to point the project URL(urls.py) to the application URL(urls.py) by using the include() function. For this, we will open the file urls.py in the root - project directory, django_with_cookie, and copy-paste the following code.
urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('welcome/template/', include('cookies.urls')),
]
As you can see in the file urls.py, we have imported the path() and include() function from the module django.urls.
The path() function has been passed the two must arguments -
A string to specify the URL pattern - 'welcome/template/'. This is the relative path to the template.
This URL pattern, combined with the URL pattern defined in the application's urls.py will be matched to the view function - templ, which is specified in the application urls.py file(stored in the application directory cookies). Therefore we have used the include() function to include and refer to the application's urls.py file.
How to load the HTML template file.
Next, we are going to show how to load the above created HTML template file template.htm, which is stored within our application folder cookies.
To load the HTML template file, we need to specify its full path in the configuration file - settings.py, which is stored in the project folder. For our example, you can find this file in the sub-directory django_with_cookie within our project django_with_cookie i.e. - django_with_cookie/django_with_cookie/settings.py.
Within the settings.py file, you need to locate the property DIRS and copy-paste the full-path to the HTML template file against it, as shown below and save the file.
And finally, it's time to execute our Django project with templates.
Executing the application of our project
To execute the cookies application of our project django_with_cookie, we just have to enter the address - http://127.0.0.1:8000/welcome/template/. This displays the form as shown below.
As you can see in the picture, the string welcome/template in the URL is the URL-pattern which gets matched to the URL pattern specified in the project urls.py file, which calls the application's urls.py and its associated view function - get_form(in the application) is executed and its response i.e.form with its elements(fields) is displayed within the HTML template file template.htm.
Next, when a user has filled the form with data in correct format.
On clicking the submit button, the user is displayed a thank you webpage(thanks.htm), as shown below.
On clicking the Log out? link, the user is displayed a logout webpage, as shown below and the saved cookie will also be deleted.
Note: We have executed this project on Firefox Mozilla. While executing this project in your browser, you may press CTRL + SHIFT + I together on your keyword to crosscheck and verify the creation and deleting of cookie at each step in your browser window.
Apart from the way that we have explained, there are a few different ways to work with cookies using Django but I hope this one will also be useful to some. Phew! This concludes the tutorial of maintaining the user-session within cooking using Django Framework. See you in the next one!