forms组件源码html
cookie与sessionpython
1 """ 2 切入点: 3 form_obj.is_valid() 4 """ 5 def is_valid(self): 6 """ 7 Returns True if the form has no errors. Otherwise, False. If errors are 8 being ignored, returns False. 9 """ 10 return self.is_bound and not self.errors 11 # 若是is_valid要返回True的话 那么self.is_bound要为True self.errors要为Flase 12 13 14 self.is_bound = data is not None or files is not None # 只要你传值了确定为True 15 16 17 @property 18 def errors(self): 19 "Returns an ErrorDict for the data provided for the form" 20 if self._errors is None: 21 self.full_clean() 22 return self._errors 23 24 # forms组件全部的功能基本都出自于该方法 25 def full_clean(self): 26 self._clean_fields() # 校验字段 + 局部钩子 27 self._clean_form() # 全局钩子 28 self._post_clean() 29 30 31 # 经过看源码获得得第二种添加钩子提示的方式 32 from django.core.exceptions import NON_FIELD_ERRORS, ValidationError 33 34 def clean_username(self): 35 username = self.cleaned_data.get('username') 36 if '666' in username: 37 # self.add_error('username', '6个粑粑憨逼') 38 raise ValidationError('6个粑粑憨逼') 39 return username 40
""" 发展史 1.网站都没有保存用户功能的需求 全部用户访问返回的结果都是同样的 eg:新闻、博客、文章... 2.出现了一些须要保存用户信息的网站 eg:淘宝、支付宝、京东... 以登录功能为例:若是不保存用户登录状态 也就意味着用户每次访问网站都须要重复的输入用户名和密码(你以为这样的网站你还想用吗?) 当用户第一次登录成功以后 将用户的用户名密码返回给用户浏览器 让用户浏览器保存在本地,以后访问网站的时候浏览器自动将保存在浏览器上的用户名和密码发送给服务端,服务端获取以后自动验证 早起这种方式具备很是大的安全隐患 优化: 当用户登录成功以后,服务端产生一个随机字符串(在服务端保存数据,用kv键值对的形式),交由客户端浏览器保存 随机字符串1:用户1相关信息 随机字符串2:用户2相关信息 随机字符串3:用户3相关信息 以后访问服务端的时候,都带着该随机字符串,服务端去数据库中比对是否有对应的随机字符串从而获取到对应的用户信息 可是若是你拿到了截获到了该随机字符串,那么你就能够冒充当前用户 其实仍是有安全隐患的 你要知道在web领域没有绝对的安全也没有绝对的不安全 """ cookie 服务端保存在客户端浏览器上的信息均可以称之为cookie 它的表现形式通常都是k:v键值对(能够有多个) session 数据是保存在服务端的而且它的表现形式通常也是k:v键值对(能够有多个) 下述内容暂时了解便可 先给我搞明白最简单的cookie与session使用再说话! 还想了解见:https://www.cnblogs.com/Dominic-Ji/p/10886902.html token session虽然数据是保存在服务端的 可是禁不住数据量大 服务端再也不保存数据 登录成功以后 将一段用户信息进行加密处理(加密算法以后你公司开发知道) 将加密以后的结果拼接在信息后面 总体返回给浏览器保存 浏览器下次访问的时候带着该信息 服务端自动切去前面一段信息再次使用本身的加密算法 跟浏览器尾部的密文进行比对 jwt认证 三段信息 (后期会讲 结合django一块儿使用) 总结: 1.cookie就是保存在客户端浏览器上的信息 2.session就是保存在服务端上的信息 3.session是基于cookie工做的(其实大部分的保存用户状态的操做都须要使用到cookie)
1 ''' 2 cookie 是一个很是具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是 3 浏览器实现的一种数据存储功能。 4 5 cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的 6 文本文件内,下一次请求同一网站时会把该cookie发送给服务器。因为cookie是存在 7 客户端上的,因此浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据 8 太多磁盘空间,因此每一个域的cookie数量是有限的。 9 '''
1 ''' 2 session 从字面上讲,就是会话。这个就相似于你和一我的交谈,你怎么知道当前和 3 你交谈的是张三而不是李四呢?对方确定有某种特征(长相等)代表他就是张三。 4 5 session 也是相似的道理,服务器要知道当前发请求给本身的是谁。为了作这种区分, 6 服务器就要给每一个客户端分配不一样的“身份标识”,而后客户端每次向服务器发请求的 7 时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么 8 保存这个“身份标识”,能够有不少种方式,对于浏览器客户端,你们都默认采用 cookie 9 的方式。 10 11 服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会 12 被销毁。这种用户信息存储方式相对cookie来讲更安全,但是session有一个缺陷:如 13 果web服务器作了负载均衡,那么下一个操做请求到了另外一台服务器的时候session会 14 丢失。
1 # 虽然cookie是服务端告诉客户端浏览器须要保存内容 2 # 可是客户端浏览器能够选择拒绝保存 若是禁止了 那么 只要是须要记录用户状态的网站登录功能都没法使用了 3 4 # 视图函数的返回值 5 return HttpResponse() 6 return render() 7 return redirect() 8 9 10 obj1 = HttpResponse() 11 # 操做cookie 12 return obj1 13 14 obj2 = render() 15 # 操做cookie 16 return obj2 17 18 obj3 = redirect() 19 # 操做cookie 20 return obj3 21 # 若是你想要操做cookie,你就不得不利用obj对象 22 23 24 """ 25 设置cookie 26 obj.set_cookie(key,value) 27 获取cookie 28 request.COOKIES.get(key) 29 在设置cookie的时候能够添加一个超时时间 30 obj.set_cookie('username', 'jason666',max_age=3,expires=3) 31 32 max_age 33 expires 34 二者都是设置超时时间的 而且都是以秒为单位 35 须要注意的是 针对IE浏览器须要使用expires 36 主动删除cookie(注销功能) 37 request.delete_cookie('username') 38 39 """ 40 # 咱们完成一个真正的登录功能 41 # 校验用户是否登录的装饰器 42 """ 43 用户若是在没有登录的状况下想访问一个须要登录的页面 44 那么先跳转到登录页面 当用户输入正确的用户名和密码以后 45 应该跳转到用户以前想要访问的页面去 而不是直接写死 46 """ 47 def login_auth(func): 48 def inner(request,*args,**kwargs): 49 # print(request.path_info) 50 # print(request.get_full_path()) # 可以获取到用户上一次想要访问的url 51 target_url = request.get_full_path() 52 if request.COOKIES.get('username'): 53 return func(request,*args,**kwargs) 54 else: 55 return redirect('/login/?next=%s'%target_url) 56 return inner 57 58 def login(request): 59 if request.method == 'POST': 60 username = request.POST.get('username') 61 password = request.POST.get('password') 62 if username == 'jason' and password == '123': 63 64 # 获取用户上一次想要访问的url 65 target_url = request.GET.get('next') # 这个结果多是None 66 if target_url: 67 obj = redirect(target_url) 68 else: 69 # 保存用户登录状态 70 obj = redirect('/home/') 71 # 让浏览器记录cookie数据 72 obj.set_cookie('username', 'jason666') 73 """ 74 浏览器不仅仅会帮你存 75 并且后面每次访问你的时候还会带着它过来 76 """ 77 # 跳转到一个须要用户登录以后才能看的页面 78 return obj 79 return render(request,'login.html') 80 81 82 @login_auth 83 def home(request): 84 # 获取cookie信息 判断你有没有 85 # if request.COOKIES.get('username') == 'jason666': 86 # return HttpResponse("我是home页面,只有登录的用户才能进来哟~") 87 # # 没有登录应该跳转到登录页面 88 # return redirect('/login/') 89 return HttpResponse("我是home页面,只有登录的用户才能进来哟~") 90 91 92 @login_auth 93 def logout(request): 94 obj = redirect('/app01/login/') 95 obj.delete_cookie('username') 96 return obj
1 from django.shortcuts import render, HttpResponse, redirect 2 3 # Create your views here. 4 5 from app01 import models 6 7 8 def login_auth(func): 9 def wrapper(request, *args, **kwargs): 10 print(request.path) 11 print(request.path_info) 12 print(request.get_full_path()) 13 target_url = request.get_full_path() 14 if request.COOKIES.get('username'): 15 return func(request, *args, **kwargs) 16 else: 17 return redirect('/app01/login/?next=%s'%target_url) 18 19 return wrapper 20 21 22 @login_auth 23 def home(request): 24 return HttpResponse('欢迎来到app01_home页面') 25 26 27 def login(request): 28 if request.method == 'POST': 29 username = request.POST.get('username') 30 password = request.POST.get('password') 31 if username == 'jason' and password == '123': 32 print(request.GET.get('next')) 33 target_url = request.GET.get('next') 34 if target_url: 35 obj = redirect(target_url) 36 else: 37 obj = redirect('/app01/home/') 38 obj.set_cookie('username', 'jason666') 39 return obj 40 else: 41 return HttpResponse('帐号密码错误') 42 return render(request, 'login.html') 43 44 45 @login_auth 46 def logout(request): 47 obj = redirect('/app01/login/') 48 obj.delete_cookie('username') 49 return obj 50 51 52 @login_auth 53 def index(request): 54 return HttpResponse('欢迎来到app01_Index页面')
获取Cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过时时间 设置Cookie rep = HttpResponse(...) rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...) 参数: key, 键 value='', 值 max_age=None, 超时时间 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie能够被任何url的页面访问 domain=None, Cookie生效的域名 secure=False, https传输 httponly=False 只能http协议传输,没法被JavaScript获取(不是绝对,底层抓包能够获取到也能够被覆盖) 删除Cookie def logout(request): rep = redirect("/login/") rep.delete_cookie("user") # 删除用户浏览器上以前设置的usercookie值 return rep
1 """ 2 session数据是保存在服务端的(存?),给客户端返回的是一个随机字符串 3 sessionid:随机字符串 4 5 1.在默认状况下操做session的时候须要django默认的一张django_session表 6 数据库迁移命令 7 django会本身建立不少表 django_session就是其中的一张 8 9 10 django默认session的过时时间是14天 11 可是你也能够人为的修改它 12 13 14 设置session 15 request.session['key'] = value 16 17 获取session 18 request.session.get('key') 19 20 设置过时时间 21 request.session.set_expiry() 22 括号内能够放四种类型的参数 23 1.整数 多少秒 24 2.日期对象 到指定日期就失效 25 3.0 一旦当前浏览器窗口关闭马上失效 26 4.不写 失效时间就取决于django内部全局session默认的失效时间 27 28 清除session 29 request.session.delete() # 只删服务端的 客户端的不删 30 request.session.flush() # 浏览器和服务端都清空(推荐使用) 31 32 33 session是保存在服务端的 可是session的保存位置能够有多种选择 34 1.MySQL 35 2.文件 36 3.redis 37 4.memcache 38 ... 39 40 41 django_session表中的数据条数是取决于浏览器的 42 同一个计算机上(IP地址)同一个浏览器只会有一条数据生效 43 (当session过时的时候可能会出现多条数据对应一个浏览器,可是该现象不会持续好久,内部会自动识别过时的数据清除 你也能够经过代码清除) 44 45 主要是为了节省服务端数据库资源 46 """ 47 48 request.session['hobby'] = 'girl' 49 """ 50 内部发送了那些事 51 1.django内部会自动帮你生成一个随机字符串 52 2.django内部自动将随机字符串和对应的数据存储到django_session表中 53 2.1先在内存中产生操做数据的缓存 54 2.2在响应结果django中间件的时候才真正的操做数据库 55 3.将产生的随机字符串返回给客户端浏览器保存 56 """ 57 request.session.get('hobby') 58 """ 59 内部发送了那些事 60 1.自动从浏览器请求中获取sessionid对应的随机字符串 61 2.拿着该随机字符串去django_session表中查找对应的数据 62 3. 63 若是比对上了 则将对应的数据取出并以字典的形式封装到request.session中 64 若是比对不上 则request.session.get()返回的是None 65 """ 66 67 68 # 利用session实现登录验证
1 from django.shortcuts import render, HttpResponse, redirect 2 3 4 # Create your views here. 5 6 7 def login_auth(func): 8 def wrapper(request, *args, **kwargs): 9 target_url = request.get_full_path() 10 if request.session.get('jason'): 11 return func(request, *args, **kwargs) 12 else: 13 return redirect('/app02/login/?next=%s'%target_url) 14 15 return wrapper 16 17 18 def login(request): 19 if request.method == 'POST': 20 username = request.POST.get('username') 21 password = request.POST.get('password') 22 if username == 'jason' and password == '123': 23 target_url = request.GET.get('next') 24 if target_url: 25 obj = redirect(target_url) 26 else: 27 obj = redirect('/app02/home/') 28 request.session['jason'] = 'haha6666' 29 request.session.set_expiry(30) 30 return obj 31 else: 32 HttpResponse('帐号或密码错误') 33 return render(request, 'login.html') 34 35 36 @login_auth 37 def home(request): 38 return HttpResponse('欢迎来到app_02home页面') 39 40 41 @login_auth 42 def index(request): 43 return HttpResponse('欢迎来到app_02index页面') 44 45 46 @login_auth 47 def logout(request): 48 request.session.flush() 49 return redirect('/app02/login/')
# 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] # 全部 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 会话session的key request.session.session_key # 将全部Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查会话session的key在数据库中是否存在 request.session.exists("session_key") # 删除当前会话的全部Session数据 request.session.delete() # 删除当前的会话数据并删除会话的Cookie。 request.session.flush() 这用于确保前面的会话数据不能够再次被用户的浏览器访问 例如,django.contrib.auth.logout() 函数中就会调用它。 # 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 若是value是个整数,session会在些秒数后失效。 * 若是value是个datatime或timedelta,session就会在这个时间后失效。 * 若是value是0,用户关闭浏览器session就会失效。 * 若是value是None,session会依赖全局session失效策略。
1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也能够是memcache),此处别名依赖缓存的设置 3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,若是为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其余公用设置项: 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,默认修改以后才保存(默认)
1 from django.views import View 2 from django.utils.decorators import method_decorator 3 """ 4 CBV中django不建议你直接给类的方法加装饰器 5 不管该装饰器能都正常给你 都不建议直接加 6 """ 7 8 # @method_decorator(login_auth,name='get') # 方式2(能够添加多个针对不一样的方法加不一样的装饰器) 9 # @method_decorator(login_auth,name='post') 10 class MyLogin(View): 11 @method_decorator(login_auth) # 方式3:它会直接做用于当前类里面的全部的方法 12 def dispatch(self, request, *args, **kwargs): 13 return super().dispatch(request,*args,**kwargs) 14 # @method_decorator(login_auth) # 方式1:指名道姓 15 def get(self,request): 16 return HttpResponse("get请求") 17 18 def post(self,request): 19 return HttpResponse('post请求')
1 """ 2 1.什么是cookie和session,你能描述一下它们的由来和工做机制吗(切勿糊弄,敷衍了事) 3 2.django中如何操做cookie和session,请写出尽可能多的操做方法,并针对session的操做 4 方法详细内部发生的事情,django默认的session失效时间是多久(切勿糊弄,敷衍了事) 5 3.面相对象中的__init__和__new__的区别是什么,利用__new__能够实现什么 6 4.如何给CBV添加装饰器,列举你所知道的几种方式 7 """
1 #入口:form_obj.is_valid() 2 3 # 校验字段和钩子函数的执行 4 5 # 报错提示 其实能够有两种方式(针对局部钩子函数) 6 1.self.add_error() 7 2.raise ValidationError() 8 9 """ 10 python源码里面使用最频繁的其实就是反射 11 """
1 # cookie与session产生缘由 2 因为http协议是无状态的 3 4 # cookie概念 5 服务端设置保存在客户端浏览器上的键值对(只要符合前面的定义均可以叫cookie) 6 cookie虽然是服务端设置的可是浏览器能够选择不保存 7 8 # session概念 9 存储在服务端上的键值对(用来标识当前用户) 须要基于cookie才能工做 10 其实大部分的保存状态的实现都须要基于cookie来作 11 12 # 在web领域没有绝对的安全 13 基本上防护措施都须要程序员本身写代码完善,而且以内完善无法杜绝
1 # 须要借助于HttpResponse对象 2 3 # 设置cookie 4 obj.set_cookie(key,value) 5 # 超时时间 6 obj.set_cookie(key,value,max_age/expires) 7 expires 针对IE须要用这个参数 数字是以秒为单位 8 # 加盐 9 obj.set_signed_cookie(key,value,salt='盐') 10 # 获取 11 request.COOKIES.get(key) 12 request.get_signed_cookie(key,salt='盐') 13 # 删除 14 obj.delete_cookie(key) 15 16 """ 17 校验用户是否登录才能访问视图函数的装饰器 18 可以记录用户在没有登录以前想要访问的页面,登录以后跳转到对应的页面 19 request.path 20 request.path_info 21 request.get_full_path() 22 """
1 """ 2 1.session是存储在服务端的 django默认状况下是须要借助于django_session表 3 来存储数据 也就意味着若是你想要操做session那么必须先执行数据库迁移命令让 4 django先把django_session表建立出来(no such table:django_session) 5 6 2.django默认的session过时时间是14天 7 8 3.session存储在服务端 能够有不少地方存储 9 1.表 10 2.文件 11 3.缓存 12 4.其余 13 ... 14 """ 15 # 设置 16 request.session[key] = value 17 """ 18 三件事 19 """ 20 # 获取 21 request.session.get(key) 22 """ 23 三件事 24 """ 25 # 删除 26 request.session.delete() 27 request.session.flush() 28 # 设置超时时间 29 request.session.set_expiry() 30 1.数字 秒数 31 2.datetime/timedelta格式 日期格式 32 3.None 参加全局失效策略 33 4.0 窗口关闭即失效 34 35 """ 36 基于session实现用户登录 37 38 有时候若是多个视图函数都须要使用到一些数据的话,你也能够考虑将该数据存储到django_session表中,方便后续的使用 39 eg: 40 登录验证码(bbs做业会涉及到) 41 """
1 """ 2 django针对CBV添加装饰器须要你导入一个模块 3 """ 4 from django.utils.decorators import method_decorator 5 6 # 第一种 7 class MyCBV(View): 8 def get(self,request): 9 return HttpResponse() 10 11 @method_decorator(login_auth) 12 def post(self,request): 13 return HttpResponse() 14 15 # 第二种 16 @method_decorator(login_auth,name='post') 17 @method_decorator(index_de,name='get') 18 class MyCBV(View): 19 def get(self,request): 20 return HttpResponse() 21 22 def post(self,request): 23 return HttpResponse() 24 25 # 第三种 26 class MyCBV(View): 27 @method_decorator(login_auth) 28 def dispatch(self,request,*args,**kwargs): 29 """ 30 看CBV源码能够得出 CBV里面全部的方法在执行以前都须要先通过 31 dispatch方法(该方法你能够当作是一个分发方法) 32 """ 33 return super().dispatch(request,*args,**kwargs) 34 35 def get(self,request): 36 return HttpResponse() 37 38 def post(self,request): 39 return HttpResponse()
""" 1.整理今日内容到博客 2.利用session实现登录验证 3.复习django阶段所学全部知识点,好好整理回顾(后面没时间了) 4.预习内容: https://www.cnblogs.com/Dominic-Ji/p/10881214.html django中间件 auth模块 """