一、forms源码解析

# from组件的切入点是is_valid()

 def is_valid(self):
"""
Returns True if the form has no errors. Otherwise, False. If errors are
being ignored, returns False.
"""
return self.is_bound and not self.errors
# 如果is_valid要返回True的话 那么self.is_bound要为True self.errors要为Flase self.is_bound = data is not None or files is not None
# 可以发现is_bound只要传值了就是true,所以直接看errors就行了 @property
def errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors self._errors = None
# _errors在定义的时候默认为None,所以这里必定会执行full_clean def full_clean(self):
"""
Cleans all of self.data and populates self._errors and
self.cleaned_data.
"""
# 定义一个存放错误信息的对象
self._errors = ErrorDict()
# is_bound 只要传值了就不为空
if not self.is_bound: # Stop further processing.
return
# 定义一个存放正确数据的字典
self.cleaned_data = {}
# If the form is permitted to be empty, and none of the form data has
# changed from the initial data, short circuit any validation.
# empty_permittedm默认为空,所以这里不会执行
if self.empty_permitted and not self.has_changed():
return # 这三条是form组件的核心
self._clean_fields() # 内部是校验数据和局部钩子
self._clean_form() # 内部是全局钩子
self._post_clean()

二、cookie与session发展史

Http请求是无状态请求,但是这种无状态的方式会让很多操作变的非常不便,比如说一个需要登录才能使用的网站,无状态的特性会让这个网站的使用处处受限。

之后便出现了一些技术可以在用户第一次登录后把用户名和密码返回给浏览器,让用户浏览器保存在本地,之后访问网站的时候浏览器自动发送这个账号和密码,服务端对其验证。

但是这样的验证方式有很大的安全隐患。

之后便出现了更高级的技术,当用户登录成功后,服务端产生一个随机字符串(存在服务端中,kv键值对形式),交给客户端浏览器保存,之后访问服务端的时候,客户端都会携带这个随机字符串,从而比对用户信息。

但是如果随机字符串被截取到了,还是可以被他人冒充用户,安全隐患依然存在。

在这样不断为了安全更新技术的时代下出现了cookie和session等保存信息的技术

  • cookie

    • 服务端保存在客户端浏览器上的信息都可以称之为cookie,多个kv键值对形式,客户端下次在访问服务端的时候会带上这个信息,以便服务端提取
  • session
    • 数据是保存在服务端的,安全性更高,且支持更多字节,且表现形式也是kv键值对,session的实现还是需要cookie作为桥接,要给每个客户端设置唯一id,以cookie记录,这样服务端就知道是谁来访问。
  • token
    • 为了解决删除数据量过大,在给浏览器保存数据之前先对数据信息加密处理
    • 浏览器在访问服务端的时候会携带加密数据,服务端判断加密格式是否是自己产生的

总结

cookie就是保存在客户端上的信息

session就是保存在服务端上的信息

session是基于cookie工作的,因为Http无状态的特性,总要有一点标识。

三、cookie操作

ps:有时候出现浏览器什么登陆都无法进行的时候,可能是浏览器设置内选择禁止了保存cookie的选项

# 在django中操作cookie就是在操作视图函数的三板斧对象:HttpResponse,redirect,render

# 设置cookie
obj = render()
obj.set_cookie(key,value)
# 设置的时候可以额外添加参数
obj.set_cookie(key,value,max_age=3,expires=3)
# max_age和expires都是设置超时时间,且以秒为单位,不过后者是针对IE浏览器 # 获取cookie
request.COOKIES.get(key)

基于cookie完成登录功能,如果想访问一个页面,没有登录前要跳转到登录页面,登录成功后跳转回要访问的页面,如果直接访问登录页面跳转到home页面

def login(request):
if request.method=='POST':
if request.POST.get('username') == 'hz' and request.POST.get('password') == '123':
# 如果直接访问login 这个结果就是None
next_page = request.GET.get("next")
if next_page:
obj = redirect(next_page)
else:
obj = redirect('/home/')
# 在浏览器中存放cookie数据,以后访问会带着它来
obj.set_cookie('hz','123')
return obj
return HttpResponse('NO')
return render(request,'login.html') def login_outter(func):
def inner(request,*args,**kwargs):
next_page = request.get_full_path()
if request.COOKIES.get('hz'):
return func(request)
return redirect(f'/login/?next={next_page}')
return inner @login_outter
def home(request):
return HttpResponse('Home')
@login_outter
def test1(request):
return HttpResponse('test1')
@login_outter
def test2(request):
return HttpResponse('test2')

四、session操作

session数据是保存在服务端的数据库中的,django中这个数据有单独的表django_session表来保存session数据

如果没有找到那就是还没执行数据库迁移命令

django默认的session的过期时间是14天,可以修改

# 设置session
request.session['key'] = value # 获取session
request.session.get('key') # 设置过期时间
# 这里的参数可以放整数:多少秒,日期对象:指定日期就失效
request.session.set_expiry() # 清楚session
request.session.delete() # 只删除服务端的,客户端的不删
request.session.flush() # 都清空,推荐使用

session数据是保存在服务端的,位置可以有多重选择:MySQL,文件,redis,memcache

django_session中的数据条数是取决于浏览器的,同一个ip同一个浏览器只会产生一条数据,如果有多个session对应一个浏览器,可能是之前session过期了还没删

request.session['name'] = 'hz'

这一条代码内部发生了三件事情:

  1. django内部帮我们生成一个随机字符串(给浏览器的一个cookie数据)
  2. django内部帮我们把随机字符串和对应的数据存档django_session表中
    1. 现在内存中产生操作数据的缓存
    2. 在响应通过django中间件的时候才是真的操作数据
  3. 将产生的随机字符串返回给浏览器保存到sessionid
request.session.get('name')

这一条代码内部发生了三件事情

  1. 自动从浏览器请求获取sessionid对应的随机字符串
  2. 那着这个字符串去django_session表中去查找数据
  3. 如果比对上了就取出数据并以字典的形式封装到reques.session中,如果没有就返回None

五、CBV如何添加装饰器

from django.views import View
from django.utils.decorators import method_decorator
"""
CBV中django不建议你直接给类的方法加装饰器
无论该装饰器能都正常给你 都不建议直接加
""" # @method_decorator(login_auth,name='get') # 方式2(可以添加多个针对不同的方法加不同的装饰器)
# @method_decorator(login_auth,name='post')
class MyLogin(View):
@method_decorator(login_auth) # 方式3:它会直接作用于当前类里面的所有的方法
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
# @method_decorator(login_auth) # 方式1:指名道姓
def get(self,request):
return HttpResponse("get请求") def post(self,request):
return HttpResponse('post请求')

day69 cookie与session的更多相关文章

  1. Cookie和Session的总结

    1.开篇 在之前学习这一段的时候我一直有点没弄清楚,其实对Session这块的理解还可以,但是Cookie感觉始终还是欠缺点火候.之后的很长一段时间都基本上很少用Cookie了,渐渐的也淡忘了这一块的 ...

  2. java的会话管理:Cookie和Session

    java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...

  3. Cookie和Session的那些事儿

    Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每 ...

  4. django的cookie和session以及内置信号、缓存

    cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...

  5. Cookie和Session的区别

    前言 HTTP是一种无状态的协议,为了分辨链接是谁发起的,就需要我们自己去解决这个问题.不然有些情况下即使是同一个网站我们每打开一个页面也都要登录一下.而Session和Cookie就是为解决这个问题 ...

  6. 本地数据Store。Cookie,Session,Cache的理解。Timer类主要用于定时性、周期性任务 的触发。刷新Store,Panel

    本地数据Store var monthStore = Ext.create('Ext.data.Store', { storeId : 'monthStore', autoLoad : false, ...

  7. Cookie与Session

    再说Cookie与Session之前,先要了解一下http协议. 何为http协议: http协议即超文本传输协议,一种基于浏览器请求与服务器响应的协议,该协议主要的特点就是它是一种无状态的协议(只针 ...

  8. 【转】Cookie和Session区别和联系详解

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  9. 理解Cookie和Session机制(转)

    目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...

随机推荐

  1. akka-typed(6) - cluster:group router, cluster-load-balancing

    先谈谈akka-typed的router actor.route 分pool router, group router两类.我们先看看pool-router的使用示范: val pool = Rout ...

  2. 构建自己的jar包上传至Mvaen中央仓库和版本更新

    构建自己的jar包上传至Mvaen中央仓库和版本更新 一直羡慕别人制造轮子,开源项目,供别人使用:我也想这样,可以自己才疏学浅,本次就将自己写小工具上传到Maven的中央仓库. 一步一步详细教程演示如 ...

  3. 前端技术 - SeaJS学习

    SeaJS 是一个模块加载器,模块加载器需要实现两个基本功能: 实现模块定义规范,这是模块系统的基础. 模块系统的启动与运行. define参数 在 CMD 规范中,一个模块就是一个文件.代码的书写格 ...

  4. SpringMVC处理json的四个步骤

    导入相关的pom依赖 在springMVC的配置文件中开启MVC驱动,<mvc:annotation-driven /> 在处理ajax请求的方法上加上注解@ResponseBody 将要 ...

  5. 手把手教你学Numpy,这些api不容错过

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Numpy专题的第5篇文章,我们来继续学习Numpy当中一些常用的数学和统计函数. 基本统计方法 在日常的工作当中,我们经常需要通过一 ...

  6. linux配置SVN服务

    在linux下配置SVN库,网上找到不少教程,但是对于有几个容易混淆的地方需要记录下, 1.在创建SVN文档库的时候,需要使用svn命令先创建出来, svnadmin create /home/svn ...

  7. Zookeeper——分布式一致性协议及Zookeeper Leader选举原理

    文章目录 一.引言 二.从ACID到CAP/BASE 三.分布式一致性协议 1. 2PC和3PC 2PC 发起事务请求 事务提交/回滚 3PC canCommit preCommit doCommit ...

  8. matplotlib 强化学习

    matplotlib 强化学习 import matplotlib.pyplot as plt ...![](https://img2020.cnblogs.com/blog/1642028/2020 ...

  9. ES6 基本语法:

    ES6.基本语法* ES6可以使用=>作为函数表达形式,简单的风格: 参数 + => +函数体;* 在JS中是以var定义一个变量 ,在ES6中是以let定义变量; let 和 var 区 ...

  10. Android studio debug apk包安装失败

    可在根目录gradle.properties中配置 android.injected.testOnly=false