Managing Sessions in Django (2024)

Understanding your Django session with examples

Managing Sessions in Django (3)

In my article “Managing Cookies in Django,” I discussed how cookies allow us to store data in the browser easily. Although there’s no doubt cookies are useful, they have the following problems:

  1. An attacker can modify contents of a cookie that could potentially break your application
  2. We can’t store sensitive data
  3. We can only store a limited amount of data in cookies. Most browsers don’t allow a cookie to store more than 4 Kb of data. Breaking data into multiple cookies causes too much overhead in each request. Further, you can’t even rely on a number of cookies allowed by the browser for each domain.

We can overcome these problems easily using sessions.

This is how sessions work:

When we use sessions, the data is not stored directly in the browser. Instead, it is stored in the server.

Django creates a unique 32-character-long random string called a session key and associates it with the session data.

The server then sends a cookie named sessionid, containing the session key, as value to the browser.

On subsequent requests, the browser sends the cookie sessionid to the server. Django then uses this cookie to retrieve session data and makes it accessible in your code.

To set up a session in Django, we need to add two things in our settings.py:

  • ‘django.contrib.sessions.middleware.SessionMiddleware'to MIDDLEWARE
  • 'django.contrib.sessions' to INSTALLED_APPS. Run python manage.py migrate to populate the table. The table has three columns: session_key, session_data, and expire_date .

These are automatically added when we create a new project with the startproject command.

We know users can configure their browsers to not accept any cookie. As a result, Django provides some convenience methods to check for cookies support in the browser. The request.sessions object provides the following three methods to check for cookies support in the browser.

set_test_cookie(): Sets a test cookie to determine whether the user’s browser supports cookies. Due to the way cookies work, you won’t be able to test this until the user’s next page request.

test_cookie_worked(): Returns either True or False, depending on whether the user’s browser accepted the test cookie. Due to the way cookies work, you’ll have to call set_test_cookie() on a previous, separate page request.

delete_test_cookie(): Deletes the test cookie. Use this to clean up after yourself.

Let's discuss an example.

def e_commerce_home(request): if request.session.test_cookie_worked():
request.session.delete_test_cookie()
else:
request.session.set_test_cookie()
messages.error(request, 'Please enable cookie')
return render(request, 'home/home.html')

When the user browses this page, it checks whether the cookie is enabled in the browser. If not, then it sends a test cookie and shows an error message to enable cookies in the browser. If the browser accepts the cookie, then it deletes the previously sent test cookie.

A Django request object has a session attribute that acts like a dictionary.

# set session data

request.session[‘user_id’] = ‘20’
request.session[‘team’] = ‘Barcelona’

# read session data

request.session.get(‘user_id’) # returns ‘20’
request.session.get(‘team’) # returns ‘Barcelona’

## delete session data

del request.session[‘user_id’]
del request.session[‘user_id’]

Let’s check the ‘django.contrib.sessions.middleware.SessionMiddleware' code to understand what it does.

  • Middlewares are called before and after the view is called. process_request(self, request) is consumed before, and process_response(self, request, response) is consumed after the view is called.
  • process_request checks if there is any cookie named sessionid(default value for settings.SESSION_COOKIE_NAME) in request.COOKIES. If found, it tries to populate the session using thesession_key column in the session database.
  • process_response checks whether request.session was modified or created. Then, it creates or saves the session data to the session database and adds a sessionid cookie to the response with session_key value. If it finds request.COOKIES is not empty and all the session data is deleted, then it deletes the session row from the database and deletes the cookie from the response, which also deletes the cookie in the browser.

Let’s create a few views to understand it clearly.

def save_session_data(request):
# set new data
request.session['user_id'] = 20
request.session['team'] = 'Barcelona'
return HttpResponse("Session Data Saved")
def access_session_data(request):
response = ""
if request.session.get('user_id'):
user_id = request.session.get('user_id')
response += "User Id : {0} <br>".format(user_id)
if request.session.get('team'):
team = request.session.get('team')
response += "Team : {0} <br>".format(team)

if not response:
return HttpResponse("No session data")
else:
return HttpResponse(response)

def delete_session_data(request):
try:
del request.session['user_id']
del request.session['team']
except KeyError:
pass

return HttpResponse("Session Data cleared")

Here’s what happens when the save_session_data() view is called.

  1. 'django.contrib.sessions.middleware.SessionMiddleware' middleware creates a new random session key and associates the session data with it.
  2. 'django.contrib.sessions.middleware.SessionMiddleware' uses the 'django.contrib.sessions' app to store the session data in the database.
  3. At last, a cookie named sessionid with a random value (session key), generated in step 1, is sent to the browser.
  4. From now on, the browser will send this sessionid cookie with every request to the server, allowing Python code to access session data in views using request.session.

When access_session_data is called after save_session_data, the sessionid cookie is available in request.COOKIES. The middleware’s process_request uses this sessionid to populate the session for this request.

In delete_session_data, we’re deleting all of the session data. The middleware identifies there’s no session data for this session, so it deletes the session row and also deletes response cookies which deletes the cookie in the browser.

By default, Django only saves to the session database when the session has been modified — that is, if any of its dictionary values have been assigned or deleted:

# Session is modified.
request.session['foo'] = 'bar'

# Session is modified.
del request.session['foo']

# Session is modified.
request.session['foo'] = {}

Another important point worth mentioning here is Django sends the session cookie to the browser only when the session data is modified. In the process, it also updates the cookie expiry time.

Session database has three columns:

session_key: To store the unique random session ID (or SID)

session_data: Django stores the session data in the encoded format. To get the raw data, use theget_decoded() method of the session object.

expire_date: The expiration date of the session cookie

Managing Sessions in Django (2024)
Top Articles
Latest Posts
Article information

Author: Sen. Ignacio Ratke

Last Updated:

Views: 5371

Rating: 4.6 / 5 (56 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Sen. Ignacio Ratke

Birthday: 1999-05-27

Address: Apt. 171 8116 Bailey Via, Roberthaven, GA 58289

Phone: +2585395768220

Job: Lead Liaison

Hobby: Lockpicking, LARPing, Lego building, Lapidary, Macrame, Book restoration, Bodybuilding

Introduction: My name is Sen. Ignacio Ratke, I am a adventurous, zealous, outstanding, agreeable, precious, excited, gifted person who loves writing and wants to share my knowledge and understanding with you.