day13 django操作cookie和session 中间件 自定义中间件

day13 django操作cookie和session 中间件 自定义中间件

昨日内容复习

  • form组件基本定义

    与models定义类基本一致
    但是这里定义在views视图层
    1.先导入
    	from django import forms
    2.定义
    class MyFormWow(forms.Form):
        #username字段最长8位,最短3位
        username=forms.CharField(max_length=8,min_length=3)
        # password字段最长8位,最短3位
        password=forms.CharField(min_length=3,max_length=8)
        # email字段必须符合邮箱格式 可以为空 默认True
        email=forms.EmailField(required=False))
    
    
  • form组件三大核心功能

    自定义数据校验功能 主要步骤
        1.搭建前端页面				标签渲染
        2.校验数据是否合法			   数据校验
        3.返回相应的提示信息			  提示信息
    #数据校验:
    	is_valid   判断所有数据是否合规 返回True 或者False
        cleaned_data 查看符合通过校验的数据,结果为字典
        errors  返回错误字段和原因
    #标签渲染
    	第一种全自动 封装程度高 不容易扩展 一般用于本地测试  
        	{{ obj.as_p }}   #自动生成 字段名字后面跟个输入框
            {{ obj.as_ul }} #自动生成 无序 用ul里面的li包裹
            {{ obj.as_table }}	#自动生成 在一行
        第二种全手动 扩展性高 书写麻烦
        	<div>
                {{ obj.username.label }}
                {{ obj.username }}
            </div>
       	    <div>
                {{ obj.password.label }}
                {{ obj.password }}
            </div>
    	第三种半自动  用for循环 结合上面两种的优点 书写简单 易扩展
        	 {% for foo in obj %}   #for循环一次就拿这个对象的类的字段一次 .参数的形式拿值
                <p>
                      {{ foo.label }}  #这获取的就相当于obj的对象.字段名
                      {{ foo }}
                </p>
    
    		{% endfor %}
    
    
    #提示信息功能
    	'''
    	#前端校验 可有可无
    	在form表单加上一个novalidate 意思是不让前端校验,让后端校验
    	<form action="" method="post" novalidate>
    	'''
        # 后端自定义提示信息 error_messages  在类定义时候使用  还有一种方式 settings字符编码里面LANGUAGE_CODE='zh-hans'  改成中文
         error_messages={
             'max_length':'用户名最多8位',
             'min_length':'用户名最少3位',
             'required':'用户名不能为空' #不能为空
         }
    邮箱的错误有一点不一样
    error_messages={
        'required': '邮箱不能为空',
        'invalid':'邮箱格式不正确'    #这个参数邮箱格式的
    }
    
    	
    
  • form组件进阶

    正则校验	
    from  django.core.validators import RegexValidator
    定义一个新的字段
    phone=forms.CharField(label='手机号',
                        validators=
                        [RegexValidator(r'^[0-9]+$', '请输入数字'),
                        RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
                        ],)
    
    钩子函数 
    	局部钩子:校验单个字段
            校验用户名是否已存在
             def clean_username(self):
                #1.获取用户名数据 在已经校验完的数据找
            	username=self.cleaned_data.get('username')
            	#2.校验用户名是否已存在
            	if username=='zhang':
                #2.1存在添加用户名存在信息
                	self.add_error('username','用户名已存在')
            	#3.返回勾出来的数据
            	return username
    
        	
        全局钩子:校验多个字段
            校验两次密码是否一致
            def clean(self):
           		password=self.cleaned_data.get('password')
            	confirm_password=self.cleaned_data.get('confirm_password')
           	 	if not password==confirm_password:
                	self.add_error('confirm_password','两次输入密码不一致')
            	return self.cleaned_data  #全局数据返回
    
                    
    
  • 其他功能补充

    label         字段名称
    required       是否必填 True必填  False非必填   默认True
    initial        默认值
    error_messages  自定义错误信息 
    widget           修改标签的属性 比如type class 等
        widget=forms.widgets.PasswordInput() #修改type
        widget=forms.widgets.TextInput(attrs={'class':'form-control'}) #修改什么属性写什么用字典的形式
    
    

今日内容概要

  • cookie与session简介

  • django操作cookie与session

  • django中间件简介

  • 如何自定义中间件

今日内容详细

  • cookie与session简介

    http协议
        四大特性
                1.基于请求响应
                2.基于TCP\IP作用于应用层之上
                3.无状态
                    基于http协议通信的服务端无法保存客户端状态
                        纵使见她千百遍 我都当她如初见
                4.()连接
    随着互联网的发展 很多网站都需要保存客户端状态 为了实现该需求
    cookie与session应运而生(最初的功能核心:保存用户状态)
        cookie:服务端让客户端浏览器保存的数据(kv键值对),cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
        session:服务端保存的关于用户相关的数据(kv键值对)
        '''session的工作需要依赖于cookie'''
        
    # 目前只要是需要用户登录的网站 基本都需要使用cookie
    	客户端浏览器也可以拒绝保存cookie
    
  • django操作cookie

    # 要想操作Cookie必须先产生对象 之后利用对象内置方法操作
    obj1 = HttpResonse()
    obj.set_cookie()  # 让浏览器保存cookie数据
    request.COOKIES.get()  # 获取浏览器携带过来的cookie数据
    obj.set_cookie(max_age\expires)  # cookie保存时间以秒为基准 IE浏览器用expires 其他用max_age
    obj.delete_cookie() 删除cookie
    
    
    #简易版本
    def home(request):
        #获取cookie  进行比对
        cookie_data=request.COOKIES.get('name')
        if cookie_data=='zhang':
            return HttpResponse('这里是home页面 请先登录之后查看')
        else:
            return redirect('/login/')
    
    def login(request):
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            if username=='zhang' and password=='123':
                #通知客户端保存cookie
                obj=redirect('/home/')
                obj.set_cookie('name','zhang')
                #跳转到首页
                return obj
        return render(request,'login.html')
    ###########多个页面需要登录才可以访问 主要用到了装饰器#################
    #装饰器
    def login_auth(func):
        def inner(request,*args,**kwargs):
            #执行home之前进行的判断
            cookie_data=request.COOKIES.get('name')
            if cookie_data=='zhang':
                res = func(request, *args, **kwargs)
                return res
            else:
                return redirect('/login/')
        return inner
    
    @login_auth
    def home(request):
        #获取cookie  进行比对
        # cookie_data=request.COOKIES.get('name')
        # if cookie_data=='zhang':
        #     return HttpResponse('这里是home页面 请先登录之后查看')
        # else:
        #     return redirect('/login/')
        return HttpResponse('这里是home页面 请先登录之后查看')
    
    @login_auth
    def index(request):
        return HttpResponse('这里是index页面 请先登录之后查看')
    
    
    def login(request):
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            if username=='zhang' and password=='123':
                #通知客户端保存cookie
                obj=redirect('/home/')
                obj.set_cookie('name','zhang')
                #跳转到首页
                return obj
        return render(request,'login.html')
    
    
    
    
    ####################登陆之后返回之前想访问的页面   比如 打开了某个页面 要登录 登陆之后 应该跳转到这个页面
    request.path.info  #仅仅获取url匹配的部分  /index/
    request.get_full_path() #获取全路径  /index/?as=1
    #装饰器
    def login_auth(func):
        def inner(request,*args,**kwargs):
            # print(request.path_info)
            # print(request.get_full_path())
            # 1.获取当前页面
            target_url=request.path_info
            #执行home之前进行的判断
            cookie_data=request.COOKIES.get('name')
            if cookie_data=='zhang':
                res = func(request, *args, **kwargs)
                return res
            else:
                #2.把这个值当成url问好后面的参数传过去
                return redirect('/login/?target_url=%s'%target_url)
        return inner
    
    def login(request):
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            if username=='zhang' and password=='123':
                #3.获取后面的值  有可能是None 因为直接在login登录的 ,那么不让他等于None 等于home
                target_url=request.GET.get('target_url','/home/')
                #通知客户端保存cookie
                obj=redirect(target_url)
                obj.set_cookie('name','zhang')
                #跳转到首页
                return obj
        return render(request,'login.html')
    
    
  • django操作session

在这里插入图片描述

#设置session
def set_session(request):
    request.session['username']='zhang666'
    return HttpResponse('德玛西亚')
    #no such table: django_session   没有这个表
    #需要直接自动创建django的表 发现里面有一个django_session  

1.django自动产生一个随机字符串
2.默认在django_session表中保存随机字符串与数据的对应关系
3.将随机字符串发送给客户端浏览器保存
    客户端浏览器保存	sessionid:随机字符串  
"""
expire_data  :django默认的session失效时间>>>:两周(14d)
"""

#获取session
request.session.get(key)  # 获取session
	1.django自动获取浏览器发送过来的cookie数据 获取随机字符串
    2.拿着随机字符串去django_session表中比对
    3.如果对应上了则获取数据并解密成明文的形式
#有几条记录 就是有几个浏览器

# 删除当前会话的所有Session数据
request.session.delete()
  
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush() 
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
  
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局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'   # 引擎
  • django中间件简介

    django中间件类似于django的门户 请求来和走都必须经过它  记得注册
    '''
    当我们需要给web后端添加一些全局相关的功能时可以使用中间件
    	1.校验每个用户的访问频率
    	2.校验每个用户的登录状态
    	3.用户黑名单、白名单
    	4.用户权限
    	...
    '''
    django默认有七个中间件 并且还支持用户自定义中间件
    自定义中间件我们可以编写五个方法
    	必须掌握的方法
    		process_request(self,request)
            	1.当请求来的时候会从上往下依次执行每一个中间件里面的该方法 最后走视图函数
                如果没有则直接下一个
                2.当该方法返回了HttpResponse对象 那么请求不再继续往后执行
                而是直接原路返回
             process_response(self,request,response)
            	1.当响应返回的时候会从下往上依次执行每一个中间件里面的该方法
                如果没有则直接下一个 该方法默认要返回response response=视图函数给浏览器返回的数据
                2.该方法返回什么浏览器就会接收到什么(也就意味着我们可以中途拦截待返回的数据做其他处理) 在里面return HttpResponse('xxx')
             # process_request方法如果直接返回HttpResonse对象则直接执行process_response并返回
            
    	需要了解的方法
        	process_view
            	路由匹配成功之后执行视图函数之前自动触发
            process_template_response
            	当返回的对象中含有render属性自动触发
            process_exception
            	当视图函数报错之后会自动触发
    

    session实现登录

    from django.shortcuts import render,HttpResponse,redirect
    
    # Create your views here.
    
    def login_auth(func):
        def inner(request,*args,**kwargs):
            target_url=request.path_info
            username=request.session.get('username')
            if username=='zhang':
                res=func(request,*args,**kwargs)
                return res
            else:
                return redirect('/login/?targeturl=%s'%target_url)
        return inner
    
    @login_auth
    def home(request):
        # username=request.session.get('username')
        # if username=='zhang':
        #     return HttpResponse('这是首页 必须登陆之后才可以访问')
        # else:
        #     return redirect('/login/')
        return HttpResponse('这是首页 必须登陆之后才可以访问')
    
    
    @login_auth
    def index(request):
        return HttpResponse('这是index 必须登陆之后才可以访问')
    
    
    @login_auth
    def func(request):
        return HttpResponse('这是func 必须登陆之后才可以访问')
    
    @login_auth
    def loginout(request):
        request.session.flush()
        return HttpResponse('退出成功')
    
    def login(request):
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            if username=='zhang' and password=='123':
                target_url = request.GET.get('targeturl', '/home/')
                request.session['username'] = username
                return redirect(target_url)
        return render(request,'login.html')
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值