一,session

当用户第一次访问某网站时,网站服务器就在内存中开辟一块空间来创建session对象,用于在“无状态”的HTTP的长会话中存储用户信息。能使用户在同一浏览器的不同页面间跳转时保持信息一致。session会在失效或过期时被清理。主要的原理性内容可以参考网络爬虫基础知识:HTTP和HTTPS、cookie和session这篇博客。

二,django中的session

1,django默认的session设置

django默认开启 session,由 settings.py 中 MIDDLEWARE 的'django.contrib.sessions.middleware.SessionMiddleware'进行状态判断,并根据判断结果调用 settings.py中INSTALLED_APPS 的'django.contrib.sessions' 进行相关处理。
默认情况下,Django将会话存储在数据库中(使用模型 Django.controller.session.models.session),如下:

尽管这样做很方便,但在某些设置中,将会话数据存储在其他地方会更快,比如可以配置Django将会话数据存储在文件系统或缓存中。通过在 settings.py 中设置 SESSION_ENGINE 来使用 django 提供多种保存 session 的方式:
1,默认使用数据库保存:

SESSION_ENGINE = 'django.contrib.sessions.backends.db'

2,使用文件保存:

SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = '/MyProject'

3,使用缓存保存:
要使用Django的缓存系统存储会话数据,首先需要确保已经配置了缓存。

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default' #设置缓存别名,默认内存缓存
  • 该方式以获取简单的缓存会话存储。 会话数据将直接存储在您的缓存中。 但是,会话数据可能不是持久性的:如果缓存已满或重新启动了缓存服务器,则可以将缓存的数据清除。

4,使用缓存+数据库保存:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
  • 对于持久化缓存数据,请将 SESSION_ENGINE 设置为“ django.contrib.sessions.backends.cached_db”。 这使用了直写式高速缓存-对高速缓存的每次写入也将被写入数据库。 如果数据不在缓存中,则会话仅使用数据库进行读取。

总之,只有在使用Memcached缓存后端时,才应该使用基于缓存的会话。本地内存缓存后端保存数据的时间不够长,因此不是一个好的选择,直接使用文件或数据库会话比通过文件或数据库缓存后端发送所有内容更快。此外,本地内存缓存后端不是多进程安全的,因此可能不是生产环境的好选择。

5,使用cookie形式保存:

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
  • 会话数据将使用Django的用于加密签名和密钥设置的工具进行存储。

6,与session相关的其他配置:

SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)

2,django中session的运行机制

1,以游客身份访问站点而未登录时,在chrome的“检查”中可以发现,当前cookie并没有生成对应的sessionid,说明一般情况下django不会为游客创建session。
2,当登陆之后,sessionid被创建并保存在默认的数据表中:

3,复制网站地址,用新窗口打开,即在登录状态下再次访问该网址,还是登陆状态,期间,浏览器先将本地cookie发送到django,django获取其中的sessionid后与默认数据表中的session_key进行比较,确定当前用户信息:

3,session的读写操作

session可理解为从request中获取的一段dict格式的数据。
1,获取session:

获取session中VCode的数据,若VCode不存在则报错:
request.session.['VCode']获取session中VCode的数据,若VCode不存在则为空:
request.session.get('VCode', '')
request.session.setdefault('VCode', '')

2,向session写入数据:

request.session['VCode'] = VCode

3,删除session中的数据:

del request.session['VCode']

4,获取session键或值

request.session.keys()
request.session.values()

5,获取session_key:

request.session.session_key

简单的session应用,已在django:使用邮箱获取验证码中有所体现:

         # 判断验证码是否已发送if not request.session.get('VCode', ''):# 发送验证码并将验证码写入sessionbutton = '重置密码'tips = '验证码已发送'password = TrueVCodeInfo = TrueVCode = str(random.randint(000000, 999999))request.session['VCode'] = VCodeuser[0].email_user('找回密码', VCode)# 匹配输入的验证码是否正确elif VCode == request.session.get('VCode'):# 密码加密处理并保存到数据库dj_ps = make_password(p, None, 'pbkdf2_sha256')user[0].password = dj_psuser[0].save()del request.session['VCode']tips = '密码已重置'

django中对cookie的简单操作可以看看cookie反爬虫应用与绕过原理。

三,session实战:使用session实现商品抢购

1,创建开发环境

使用python3.7与django2.2.14,项目结构如下:

2,创建商品模型与数据

index/models.py:
from django.db import modelsclass Product(models.Model):id = models.AutoField('序号', primary_key=True)name = models.CharField('名称', max_length=50)slogan = models.CharField('简介', max_length=50)sell = models.CharField('宣传', max_length=50)price = models.IntegerField('价格')photo = models.CharField('相片', max_length=50)# 设置返回值def __str__(self):return self.nameclass Meta:verbose_name = '商品信息'verbose_name_plural = verbose_name

迁移数据后,添加商品信息:

3,模板文件

templates/index.html:
<!DOCTYPE html>
<html>
<head><title>商城首页</title>{% load static %}<link rel="stylesheet" href="{% static "css/hw_index.css" %}">
</head>
<body>
<div id="top_main"><div class="lf" id="my_hw">当前用户:{{ user.username }}</div><div class="lf" id="settle_up"><a href="{% url 'index:order' %}">订单信息</a></div>
</div>
<section id="main"><div class="layout"><div class="fl u-4-3 lf"><ul>{% for p in products %}<li class="channel-pro-item"><div class="p-img"><img src="{% static p.photo %}"></div><div class="p-name lf"><a href="#">{{ p.name }}</a></div><div class="p-shining"><div class="p-slogan">{{ p.slogan }}</div><div class="p-promotions">{{ p.sell }}</div></div><div class="p-price"><em>¥</em><span>{{ p.price }}</span></div><div class="p-button lf"><a href="{% url 'index:index' %}?id={{ p.id }}">立即抢购</a></div></li>{% if forloop.counter == 2 %}<div class="hr-2"></div>{% endif %}{% endfor %}</ul></div></div>
</section>
</body>
</html>templates/order.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>订单信息</title>
{% load static %}
<link rel="stylesheet" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" href="{% static 'css/carts.css' %}">
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/carts.js' %}"></script>
</head>
<body>
<section class="cartMain"><div class="cartMain_hd"><ul class="order_lists cartTop"><li class="list_chk"><input type="checkbox" id="all" class="whole_check"><label for="all"></label>全选</li><li class="list_con">商品信息</li><li class="list_price">单价</li><li class="list_amount">数量</li><li class="list_sum">金额</li><li class="list_op">操作</li><li class="list_op"><a href="{% url 'index:index' %}">返回首页</a></li></ul></div><div class="cartBox"><div class="shop_info"><div class="all_check"><!--店铺全选--><input type="checkbox" id="shop_b" class="shopChoice"><label for="shop_b" class="shop"></label></div><div class="shop_name">店铺:<a href="javascript:;">MyDjango</a></div></div><div class="order_content">{% for p in products %}<ul class="order_lists"><li class="list_chk"><input type="checkbox" id="checkbox_4" class="son_check"><label for="checkbox_4"></label></li><li class="list_con"><div class="list_text"><a href="javascript:;">{{ p.name }}</a></div></li><li class="list_price"><p class="price">¥{{ p.price }}</p></li><li class="list_amount"><div class="amount_box"><a href="javascript:;" class="reduce reSty">-</a><input type="text" value="1" class="sum"><a href="javascript:;" class="plus">+</a></div></li><li class="list_sum"><p class="sum_price">¥{{ p.price }}</p></li><li class="list_op"><p class="del"><a href="{% url 'index:order' %}?id={{ p.id }}" class="delBtn">移除商品</a></p></li></ul>{% endfor %}</div></div><!--底部--><div class="bar-wrapper"><div class="bar-right"><div class="piece">已选商品<strong class="piece_num">0</strong>件</div><div class="totalMoney">共计: <strong class="total_text">0.00</strong></div><div class="calBtn"><a href="javascript:;">结算</a></div></div></div>
</section>
</body>
</html>

4,功能实现

from django.shortcuts import render, redirect
from .models import Product
from django.contrib.auth.decorators import login_required# 商品信息展示
@login_required(login_url='/admin/login')
def index(request):# 用户抢购时,获取商品idid = request.GET.get('id', '')if id:# 获取存储在Session的idListidList = request.session.get('idList', [])# 判断当前请求参数是否已存储在Sessionif not id in idList:# 将商品的主键id存储在idListidList.append(id)# 更新Session的idListrequest.session['idList'] = idListreturn redirect('/')# 查询所有商品信息products = Product.objects.all()return render(request, 'index.html', locals())# 订单确认
def orderView(request):idList = request.session.get('idList', [])del_id = request.GET.get('id', '')# 判断是否为空,若非空,删除Session里的商品信息if del_id in idList:# 删除Session里某个商品的主键idList.remove(del_id)# 将删除后的数据覆盖原来的Sessionrequest.session['idList'] = idList# 根据idList查询商品的所有信息products = Product.objects.filter(id__in=idList)return render(request, 'order.html', locals())
  • 在点击立即抢购后,首先在模板里向请求中添加了商品id后,由index路由将请求转发给index进行处理,index将这个id加入idList实现购物车商品添加功能,然后发生了一次刷新当前页面的重定向。
  • 进入订单信息点击移除商品后,在模板里向请求中添加了商品id,由order路由将请求转发给orderView进行处理,orderView将这个id从idList中删除,实现购物车商品删除功能。
  • 订单信息页面中的商品选择、数量统计、总价统计由JavaScript完成。

5,运行

登录后进入商品信息页,就会会产生session信息:

点击商品的立即抢购后,会将商品id加入到session的idList中,可以打印出session信息进行查看:

print(request.session.values())
# 在抢购了两件商品之后:
dict_values(['1', 'django.contrib.auth.backends.ModelBackend', '7f4dfdaf193f6c0f7e62792ab67eb835a0c86168', ['1', '3']])

进入订单界面:

当选择新窗口登录并打开订单信息界面时,直接跳过了登陆页面,还会发现之前加入的商品都还在,也就是说,我们通过session成功保存了用户相关信息,实现了用户在不同窗口间的信息一致功能。但如果用另一个浏览器进行访问,则还是需要重新登陆,这也是session/cookie原理的体现。

django:session会话控制相关推荐

  1. Django源码分析5:session会话中间件分析

    django源码分析 本文环境python3.5.2,django1.10.x系列 1.这次分析django框架中的会话中间件. 2.会话保持是目前框架都支持的一个功能,因为http是无状态协议,无法 ...

  2. php会话控制区别和流程,PHP会话控制:cookie和session区别与用法深入理解_后端开发...

    PHP Swoole 基本使用_后端开发 Swoole是php的一个异步.并行.高性能的网络通信引擎,可以用Swoole做一些想http.websocket的服务器,Swoole提供了异步多线程服务器 ...

  3. PHP学习之会话控制session、cookie

    会话控制是一种面向连接的可靠通信方式,通常根据会话控制记录判断用户登录的行为.比如:网购和处理邮件时,你可能需要访问多个页面,但只要你不退出,在同一个系统上,多个页面之间互相切换时,还能保持用户的登录 ...

  4. 三、Flask_会话控制与请求钩子

    1. 会话控制 会话控制: cookie 和 session 在flask中会话控制的保存主要通过request和response来完成 session本质上就是保存在服务端中的一个文件,文件中存储了 ...

  5. 限制会话id服务端不共享_会话控制 - able-woman - 博客园

    会话控制是什么? cookie和session都是跟踪整个会话过程的技术手段.而会话,就是用户通过浏览器和服务器的一次通话. 为什么要有会话控制? 因为HTTP协议是无状态的,服务器不知道用户上一次做 ...

  6. WEB开发中的会话控制

    Session技术是网站技术中不可或缺的一个重点.主要用户跟踪用户的登录信息,实现跨页面传值.为了讲解会话控制,首先也是给同学们展示效果.如果网站地址被公开,如果没有使用session技术的页面一定会 ...

  7. PHP学习总结(会话控制)

    最近刚做完一个简易的登陆注册小项目,当时做的时候匆忙,现在来详细的了解一下PHP会话控制这方面的知识. cookie和seesion技术出现的原因: 当一个用户请求一个页面时,再请求同一个网站上的另外 ...

  8. PHP面试 PHP基础知识 八(会话控制)

    ---恢复内容开始--- PHP会话控制技术 首先了解一下为什么要使用会话控制技术? 本身web 与服务器的交互是通过HTTP协议来实现的,而HTTP协议又是无状态协议.就是说明HTTP协议没有一个內 ...

  9. PHP - 会话控制

    第12章 会话控制 学习要点: 1.Cookie的应用 2.Session会话处理 HTTP(超文本传输协议)定义了通过万维网(WWW)传输文本.图形.视频和所有其他数据所有的规则.HTTP是一种无状 ...

最新文章

  1. Quartz动态添加、修改和删除定时任务
  2. 以完美主义的名义,拖延症在公开掠夺
  3. C语言放大字符怎么编程,c语言中怎么将个别字体放大,如9,将其放大,怎么编程呢?...
  4. 如何集成Spring和Struts(实例说明)
  5. PHP + Redis 实现一个简单的twitter
  6. python打印数组中期望元素的位置
  7. python3 实现对比conf 文件差异
  8. LeetCode MySQL 1607. 没有卖出的卖家
  9. ofdm原理_OFDM技术简介
  10. LAMP+Zabbix课程总结
  11. 软件工程第一次作业-谢旭军
  12. python在线游戏_几个简单的python小游戏
  13. 《东周列国志》第六十七回 卢蒲癸计逐庆封 楚灵王大合诸侯
  14. pyspark案例系列11-ALS推荐算法
  15. 【渝粤题库】广东开放大学 建筑构造 形成性考核
  16. matlab计算纹波电压,如何估算开关电源纹波电压?
  17. Git暂存区有什么用
  18. Error:java: 读取xxx.jar时出错; zip file is empty
  19. python 安卓模拟点击_python模拟android屏幕高频点击工具
  20. 小游戏推广项目,适合新手操作的网路项目

热门文章

  1. 今天【分享】一个好用的文献管理软件——Zetero
  2. 数据结构与算法----问答2023
  3. 杰理AC692N---提示音压缩和修改
  4. java cms视频_【视频+源码】JAVA CMS系统项目实战
  5. 高清通话蓝牙耳机推荐,打电话专用的耳机分享
  6. Python课堂15--面向对象-继承
  7. 由Http Post提交遇到的一个坑,深入详解4种Post发送数据编码方式
  8. 基于电商平台的商品的关键词文本匹配任务 有代码有数据
  9. 深度学习基础理论探索(一):激活函数、梯度消失
  10. scrapy框架之增量式爬虫