day13 django操作cookie和session 中间件 自定义中间件
昨日内容复习
-
form组件基本定义 与models定义类基本一致
但是这里定义在views视图层
1.先导入
from django import forms
2.定义
class MyFormWow(forms.Form):
username=forms.CharField(max_length=8,min_length=3)
password=forms.CharField(min_length=3,max_length=8)
email=forms.EmailField(required=False))
-
form组件三大核心功能 自定义数据校验功能 主要步骤
1.搭建前端页面 标签渲染
2.校验数据是否合法 数据校验
3.返回相应的提示信息 提示信息
is_valid 判断所有数据是否合规 返回True 或者False
cleaned_data 查看符合通过校验的数据,结果为字典
errors 返回错误字段和原因
第一种全自动 封装程度高 不容易扩展 一般用于本地测试
{{ obj.as_p }}
{{ obj.as_ul }}
{{ obj.as_table }}
第二种全手动 扩展性高 书写麻烦
<div>
{{ obj.username.label }}
{{ obj.username }}
</div>
<div>
{{ obj.password.label }}
{{ obj.password }}
</div>
第三种半自动 用for循环 结合上面两种的优点 书写简单 易扩展
{% for foo in obj %}
<p>
{{ foo.label }}
{{ foo }}
</p>
{% endfor %}
'''
#前端校验 可有可无
在form表单加上一个novalidate 意思是不让前端校验,让后端校验
<form action="" method="post" novalidate>
'''
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):
username=self.cleaned_data.get('username')
if username=='zhang':
self.add_error('username','用户名已存在')
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()
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
-
django操作cookie
obj1 = HttpResonse()
obj.set_cookie()
request.COOKIES.get()
obj.set_cookie(max_age\expires)
obj.delete_cookie() 删除cookie
def home(request):
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':
obj=redirect('/home/')
obj.set_cookie('name','zhang')
return obj
return render(request,'login.html')
def login_auth(func):
def inner(request,*args,**kwargs):
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):
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':
obj=redirect('/home/')
obj.set_cookie('name','zhang')
return obj
return render(request,'login.html')
request.path.info
request.get_full_path()
def login_auth(func):
def inner(request,*args,**kwargs):
target_url=request.path_info
cookie_data=request.COOKIES.get('name')
if cookie_data=='zhang':
res = func(request, *args, **kwargs)
return res
else:
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':
target_url=request.GET.get('target_url','/home/')
obj=redirect(target_url)
obj.set_cookie('name','zhang')
return obj
return render(request,'login.html')
-
django操作session
def set_session(request):
request.session['username']='zhang666'
return HttpResponse('德玛西亚')
1.django自动产生一个随机字符串
2.默认在django_session表中保存随机字符串与数据的对应关系
3.将随机字符串发送给客户端浏览器保存
客户端浏览器保存 sessionid:随机字符串
"""
expire_data :django默认的session失效时间>>>:两周(14d)
"""
request.session.get(key)
1.django自动获取浏览器发送过来的cookie数据 获取随机字符串
2.拿着随机字符串去django_session表中比对
3.如果对应上了则获取数据并解密成明文的形式
request.session.delete()
request.session.flush()
这用于确保前面的会话数据不可以再次被用户的浏览器访问
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'
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = None
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_view
路由匹配成功之后执行视图函数之前自动触发
process_template_response
当返回的对象中含有render属性自动触发
process_exception
当视图函数报错之后会自动触发
session实现登录 from django.shortcuts import render,HttpResponse,redirect
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):
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')
|