本文通过示例演示 Django 中如何创建、查询、删除 Cookie 与 Session。
在Web开发中,使用 session 来完成会话跟踪,session 底层依赖 Cookie 技术。出于安全原因,需要对关键信息(比如密码)进行加密,cookie 很难满足这个需求,所以出现了 session。简单画了一个图:
Session | Cookie | |
增 | request.session['session_name'] = 'session_value' | response.set_cookie(cookie_name, value, max_age = None, expires = None) |
删 | 删除一组键值对: request.session.pop('session_name') 或 del request.session['session_name'] | response.delete_cookie(cookie_name) |
删除整条记录: request.session.flush() 或 request.session.clear() | ||
查 | session_value = request.session.get('session_name') | request.COOKIES['cookie_Name'] |
session_value = request.session['session_name'] |
注意:在Cookie 操作中,“查询”操作,需要服务器端首先从 request 请求头中提取出 Cookie,所以前缀是 request。
一个简单的示例,不存储数据,无需修改 models.py。
views.py
from django.shortcuts import HttpResponse
def SetCookie(request):
response = HttpResponse('Create the Cookie')
response.set_cookie('bookname','fan_ren_xiu_xian_zhuan')
return response
def GetCookie(request):
bookname = request.COOKIES['bookname']
return HttpResponse(f'The book name is: {bookname}')
def UpdateCookie(request):
response = HttpResponse('Update the Cookie!')
response.set_cookie('bookname','wan_gu_shen_di')
return response
def DeleteCookie(request):
response = HttpResponse('Delete the Cookie!')
response.delete_cookie('bookname')
return response
urls.py
from django.contrib import admin
from django.urls import path
from .views import SetCookie, GetCookie, UpdateCookie, DeleteCookie
urlpatterns = [
path('admin/', admin.site.urls),
path('setcookie/',SetCookie),
path('getcookie/',GetCookie),
path('updatecookie/',UpdateCookie),
path('deletecookie/',DeleteCookie),
]
使用浏览器验证,我使用的是火狐。
浏览器端发送请求,服务器端返回 Set-Cookie 响应头到浏览器端,用于创建Cookie:
同时,查询浏览器,已经存储了相应 Cookie:
后续的访问,浏览器的请求头中都携带了Cookie:
更新Cookie时,服务器端将新 Cookie 通过响应头发送到浏览器端:
查询浏览器存储的 Cookie,已经变成新 Cookie 了:
删除 Cookie,就是将 Cookie 设置为空,同时将过期时间设置为1970年1月1日 00:00:00。
本示例中使用了数据库。提前创建好数据库,session数据会存储到 django_session 表中。
views.py
from django.shortcuts import HttpResponse
def SetSession(request):
request.session['book_name1'] = 'fan_ren_xiu_xian_zhuan'
request.session['book_name2'] = 'wan_gu_shen_di'
return HttpResponse('The Session has been successfully set')
def GetSession(request):
book_name1 = request.session.get('book_name1')
book_name2 = request.session.get('book_name2')
return HttpResponse(f'The book_name1 is: {book_name1}, the book_name2 is: {book_name2}')
def DelSessionKey(request):
# 方法1: del request.session['book_name1']
# 方法2: request.session.pop('book_name1')
request.session.pop('book_name1')
return HttpResponse('The Session key book_name1 has been delete')
def DelSession(request):
request.session.flush()
return HttpResponse('The Session has been delete')
def Set_expiry(request):
request.session.set_expiry(300)
return HttpResponse('The Session last 5 minutes.')
urls.py
from django.contrib import admin
from django.urls import path
from .views import SetSession, GetSession, DelSessionKey, DelSession, Set_expiry
urlpatterns = [
path('admin/', admin.site.urls),
path('setsession/',SetSession),
path('getsession/',GetSession),
path('delsessionkey/',DelSessionKey),
path('delsession/',DelSession),
path('setexpiry/',Set_expiry),
]
使用火狐浏览器验证。发送请求,响应头中返回 sessionid。
同时 sessionid 已经存储在浏览器中:
此时数据库中已经有了对应的 session 记录,过期时间默认14天,所以是12月9日:
方法1:通过网页查询 session,可以正常获取到解码之后的值。
方法2:django shell 中进行查询操作。使用 python3 manage.py shell 命令进入命令行,根据 sessionid 创建实例化对象,使用 get_decoded() 方法进行解码,得到 session 值。最后,可以使用 delete() 方法删除整个 session。
访问 delsessionkey/ 路径,删除一组键值对:
从数据库中可以观察到,因为删除一组键值对,数据有了修改,所以 session_data 和 expire_date 都改变了。session_data 存的是用户的信息,即多个 request.session[“key”]=value,且是密文。expire_date 存的是该条记录的过期时间(默认14天)。
再次查询数据,book_name1 已经取不到了。
访问路径 delsession/,删除整个 session:
[1] 菜鸟教程.Django cookie 与 session[EB/OL].[2022-11-25].https://www.runoob.com/django/django-cookie-session.html.
[2] AskPython.Django Cookies – Setting up User Cookies in Django[EB/OL].[2022-11-25].https://www.askpython.com/django/django-cookies.
[3] AskPython.Django Sessions – Setting up User Sessions with Django[EB/OL].[2022-11-25].https://www.askpython.com/django/django-sessions.
[4] Django Software Foundation.如何使用会话[EB/OL].[2022-11-25].https://docs.djangoproject.com/zh-hans/4.1/topics/http/sessions/.