Django Cookie Session Example

This example is a user login and registration example implemented with Python Django, it demos below key points.

  1. How to set/get cookie and session values in Django.
  2. How to avoid cross site request forgery attack.
  3. How to include other template html page in Django template html page.
  4. How to map the root url of Django web application.
  5. How to map url exactly in Django.

1. How To Get/Set Cookie Values In Django.

  1. Import django.http.HttpResponseRedirect class.
    django.http import HttpResponse, HttpResponseRedirect
  2. Create an instance of django.http.HttpResponseRedirect.
    response = HttpResponseRedirect('/user/login_success/')
  3. Invoke set_cookie method to set cookie name, value and expiration time.
    response.set_cookie('user_name', user_name, 3600)
  4. Use django.http.HttpRequest.COOKIES to get cookie value.
    user_name = request.COOKIES.get('user_name','')

2. How To Get/Set Session Values In Django.

  1. Before you can use session in Django, you need to run migrate command to create table django_session in the project sqlite db, otherwise you will get no such table: django_session error message like below.
    django no such table django_session error
  2. You can run migrate command in either Django project folder in a terminal or in PyCharm command console.
  3. Open a terminal and cd into Django project folder, then run python3 manage.py migrateto create django_session table.
  4. Or if you coding in PyCharm, click Tools —> Run manage.py Task… menu item, then execute migrate command in bottom command console.
    pycharm run migrate command in console
  5. When you run the example, you can use Sqlite Studio to browse the table django_session data like below. You can refer How To Install SQLite3 On Mac to learn more.
    browse django session data in sqlite sutdio
  6. Use django.http.HttpRequest object session attribute to set session name,value.
    request.session['user_name'] = user_name
  7. Use django.http.HttpRequest object session attribute get method to get session value by name.
    user_name = request.session.get('user_name','')

3. How To Avoid Cross Site Request Forgery(CSRF) Attack In Django.

If you do not know what is CSRF please goto Wikipedia CSRF page to learn.

If your Django web app do not contain below code to avoid CSRF, when you request your web page, you will get below error page. The error message is CSRF verification failed. Request aborted.

web site cross site request forgery error page

To avoid above CSRF error, you need to add {% csrf_token %} in your html form page.

<form method="post" action="/user/do_login/">
      ......
      <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
      {% csrf_token %}
</form>

Then Django will create a hidden field in the result web page html form like below. The hidden field value will be used to identify the client request.

<input type="hidden" name="csrfmiddlewaretoken" value="4J9X89qeZS6ecrO9Z9DBkOaUOCfUpeKQZ0HxJT1xj9zyBmQRx3RMxnSMZlDkMbju">

4. How To Include Other Django Template Html Page.

Use Django html template include tag to include other template html page.

{% include "./menu_bar.html" %}

5. How To Map Root Url For Django Web Application.

Django define url mapping in application urls.py file. If you want to map Django web app root url, then just use regular expression ^$ as the url path expression.

url(r'^$', views.home_page, name='home_page'),

6. How To Map Url Exactly In Django.

One Django project can contain multiple web applications, each web application can has it’s own root web context path. In this example the Django project name is DjangoHelloWorld, and the web application name is user_register_login.

READ :   How To Add Models To Django Admin Site

We map url path user/ to web app user_register_login in the project urls.py file like below. The path start with ^ that means the request url context path should start with user/.

url(r'^user/', include('user_register_login.urls')),

So when request url http://127.0.0.1:8000/user/register/, it will find the request url path register/ mapped view function name in Django web app user_register_login‘s urls.py file.

url(r'^register/$', views.user_register, name='user_register'),

As you can see in above url function, the path start with ^ and end with $, this means the path should be register/ exactly. And the path register/ is relative to the web app context path user/, so the full request path should be http://127.0.0.1:8000/user/register/.

7. Django Cookie Session Example Source Code.

This example is based on Hello World Django PyCharm Example project. It just add a web application user_register_login in it. Below is the project source files list in PyCharm.

Please note do not forget add app user_register_login in the project settings.py file INSTALLED_APP section like below.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'my_hello_world',
    'user_register_login',
]

pycharm django user register and login example source files

Before dive into the source code, first let us watch how the example looks like when execute it.

7.1 Project urls.py file.

File path is DjangoHelloWorld/DjangoHelloWorld/urls.py.

from django.contrib import admin
from django.urls import path, include
from django.conf.urls import url

urlpatterns = [
    path('admin/', admin.site.urls),

    path('index/', include('my_hello_world.urls')),

    url(r'^$', include('user_register_login.urls')),

    url(r'^user/', include('user_register_login.urls')),
]

7.2 user_register_login urls.py.

File path is DjangoHelloWorld/user_register_login/urls.py.

from django.conf.urls import url
from django.urls import path
# import views from local directory.
from . import views

urlpatterns = [

    # do not use empty string in the url request path, it will intercept all request url with all request path value.
    # url(r'', views.home_page, name='home_page'),

    # if you want to intercept the django app root path request just use url path r'^$' to map it.
    # Then following url mapping will handle request http://127.0.0.1:8000/ with view function home_page.
    url(r'^$', views.home_page, name='home_page'),

    # Map to url http://127.0.0.1:8000/user/home/
    url(r'^home/$', views.home_page, name='home_page'),

    # When user browse http://localhost:8000/user/do_login, it will invoke the do_login function defined in views.py.
    url(r'^do_login/$', views.do_login, name='do_login'),

    # Map to url http://127.0.0.1:8000/user/login_success/, this url will be invoked after login success.
    url(r'^login_success/$', views.login_success, name='login_success'),

    # Map to url http://127.0.0.1:8000/user/register/
    url(r'^register/$', views.user_register, name='user_register'),

    # When user browse http://localhost:8000/user/do_register, it will invoke the do_register function defined in views.py.
    url(r'^do_register/$', views.do_register, name='do_register'),

    # Map to url http://127.0.0.1:8000/user/register_success/, this url will be invoked after register success.
    url(r'^register_success/$', views.register_success, name='register_success'),
]

7.3 user_register_login views.py.

from django.shortcuts import render
from django.http import HttpResponseRedirect

# Create your views here.

def home_page(request):
    return render(request, 'user_register_login/user_login.html')

def do_login(request):

    request_method = request.method

    print('request_method = ' + request_method)

    if request_method == 'POST':
        user_name = request.POST.get('user_name','')
        user_password = request.POST.get('user_password', '')

        if user_name == 'dev2qa.com' and user_password == 'dev2qa.com':
            # show login success info to client browser directly.
            # return HttpResponse('Login Success!')
            print(request.path_info)
            # redirect web page to login success page.
            response = HttpResponseRedirect('/user/login_success/')
            # set cookie to transfer user name to login success page.
            response.set_cookie('user_name', user_name, 3600)
            return response
        else:
            error_json = {'error_message' : 'User name or password is not correct.'}
            return render(request, 'user_register_login/user_login.html', error_json)
    else:
        return render(request, 'user_register_login/user_login.html')

def login_success(request):
    # get user name from cookie.
    user_name = request.COOKIES.get('user_name','')
    # pass user_name to display web page.
    return render(request, 'user_register_login/user_login_success.html', {'user_name':user_name})

def user_register(request):
    # clear session value before register.
    request.session['user_name'] = ''
    request.session['user_password'] = ''
    request.session['user_email'] = ''
    return render(request, 'user_register_login/user_register.html', {'user_name':'','user_password':'','user_email':''})

def do_register(request):
    request_method = request.method

    print('request_method = ' + request_method)

    if request_method == 'POST':
        user_name = request.POST.get('user_name', '')
        user_password = request.POST.get('user_password', '')
        user_email = request.POST.get('user_email', '')

        if len(user_name) > 0 and len(user_password) > 0 and len(user_email) > 0:
            # redirect web page to register success page.
            response = HttpResponseRedirect('/user/register_success/')
            # set user name, pasword and email value in session.
            request.session['user_name'] = user_name
            request.session['user_password'] = user_password
            request.session['user_email'] = user_email
            return response
        else:
            error_json = {'error_message': 'User name, password and email can not be empty.'}
            return render(request, 'user_register_login/user_register.html', error_json)
    else:
        return render(request, 'user_register_login/user_register.html')


def register_success(request):
    # get user name, password, email value from session.
    user_name = request.session.get('user_name','')
    user_password = request.session.get('user_password', '')
    user_email = request.session.get('user_email', '')
    # pass user_name, user_password and user_email to display web page.
    return render(request, 'user_register_login/user_register_success.html', {'user_name':user_name,'user_password':user_password,'user_email':user_email})

7.4 user_register_login template html files.

7.4.1 menu_bar.html

This file will be included in other template html file.

<a href="/" style="margin-right: 15px">Login</a><a href="/user/register/">Register</a><br/>
7.4.2 user_login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Login Page</title>
</head>
<body>
{% include "./menu_bar.html" %}
<h3>User Login Form</h3>
<form method="post" action="/user/do_login/">

    {% if error_message %}
          <font color="red">{{ error_message }}</font><br/>
    {% endif %}
    User Name: <input name="user_name" type="text" placeholder="user_name"><br/>

    Password: <input name="user_password" type="password" placeholder="user_password"><br/>

    <button type="submit">Login</button>

    <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
    {% csrf_token %}

</form>
</body>
</html>
7.4.3 user_login_success.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Login Success</title>
</head>
<body>
{% include "./menu_bar.html" %}
Hello {{ user_name }}, your user name and password is correct.
</body>
</html>
7.4.4 user_register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Register Page</title>
</head>
<body>
{% include "./menu_bar.html" %}
<h3>User Register Form</h3>
<form method="post" action="/user/do_register/">

    {% if error_message %}
          <font color="red">{{ error_message }}</font><br/>
    {% endif %}
    User Name: <input name="user_name" type="text" placeholder="user_name" /><br/>

    Password: <input name="user_password" type="password" placeholder="user_password" /><br/>

    Email: <input name="user_email" type="text" placeholder="user_email" /><br/>

    <button type="submit">Register</button>

    <!-- this template tag will avoid 'CSRF verification failed. Request aborted' error. -->
    {% csrf_token %}

</form>
</body>
</html>
7.4.5 user_register_success.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Register Success</title>
</head>
<body>
{% include "./menu_bar.html" %}
Hello {{ user_name }}, below is your register information.<br/>
User Name : {{ user_name }}<br/>
User Password : {{ user_password }}<br/>
User Email : {{ user_email }}<br/>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.