第二十二章 Django会话与表单验证
第一课 模板回顾
1.基本操作
def func(req):
return render(req,'index.html',{'val':[1,2,3...]}
#index.html
<h1>{{val.0}}
2.继承:一个html页面只能继承一个模板
extends 'layout.html'
{{ block xxx}}
...
{{endblock}}
3.组件:
{{include tag.html}}
4.自定义函数:
simple_tag:任意参数,不能用于条件。
filter: 参数限制,不能加空格,可以用于条件判断。
第二课 session
1.session的原理:
Cookie是保存在用户客户端的键值对
Session是保存在服务器端的键值对
实例:
def login(req):
if req.method=="GET":
return render(req,'login.html')
elif req.method=="POST":
u=req.POST.get('username')
p=req.POST.get('pwd')
if u=='root' and p=='123':
#1.生成随机字符串
#2.写到用户浏览器cookie
#3.保存到session
#4.在随机字符串对应的字典中设置相关内容...
#1/2/3/4合并为 设置session值
req.session['username']=u
req.session['is_login']=True
if req.POST.get('rmb',None)=='1':
#超时时间,10秒
req.session.set_expiry(10)
return redirect('/index/')
else:
return render(req,'login.html')
def index(req):
#session获取值
if req.session.get('is_login'):
return render(req,'index.html',{'username':req.session['username']})
else:
return HttpResponse('滚')
运行Session之前,需要在命令行输入:
python manage.py makemigrations
python manage.py migrate
2.session的基本操作:
session获取值:
req.session['k1']# 会报错
req.session.get('k1',None) #不会报错
session设置值:
req.session['k1']='v1'
req.session.setdefault('k1',123)#存在则不设置
session删除:
del req.session['k1']
session注销(退出登录):
后台views代码:
def logout(req):
req.session.clear()
return redirect('/login/')
前端代码:
<a href="/logout">注销</a>
session设置超时时间:
req.session.set_expiry(10)#10秒
3.session的配置(setting.py):
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,默认修改之后才保存(默认)
第三课 CSRF
1.基于form表单的post加CSRF:
前端代码:
<form action="/fm/" method="post">
{% csrf_token %}
....
<p><input type="submit" value="提交"></p>
</form>
2.给所有Ajax加CSRF的配置:
前端代码:
<script src="/static/jquery-3.2.1.js"></script>
<script>
$(function () {
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' }
});
$('#btn').click(function () {
$.ajax({
url:'/login/',
type:'POST',
data:{'user':'root','pwd':'123'},
suceess:function (arg) {
}
})
});
$('#btn2').click(function () {
$.ajax({
url:'/login/',
type:'POST',
data:{'user':'root','pwd':'123'},
suceess:function (arg) {
}
})
})
})
</script>
第四课 中间件(管道)
1.在项目下建立目录:Middle 并在目录下创建py文件:m1.py
m1.py中的代码:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class row1(MiddlewareMixin):
def process_request(self,req):
print('路人甲')
# return HttpResponse('一旦process_request有返回值就截住啦!')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("中间件1view")
def process_response(self,req,response):
print('路人甲返回')
return response
class row2(MiddlewareMixin):
def process_request(self,req):
print('路人乙')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("中间件2view")
def process_response(self,req,response):
print('路人乙返回')
return response
class row3(MiddlewareMixin):
def process_request(self,req):
print('路人丙')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("中间件3view")
def process_response(self,req,response):
print('路人丙返回')
return response
2.在setting.py文件中MIDDLEWARE 列表中加入代码:
MIDDLEWARE = [
....
'Middle.m1.row1',
'Middle.m1.row2',
'Middle.m1.row3',
]
3.views.py中增加函数:
def test(req):
print('路人丁--》没带钱。')
return HttpResponse('ok')
4.加入url.py路径后,访问路径,运行输出:
路人甲
路人乙
路人丙
中间件1view
中间件2view
中间件3view
路人丁--》没带钱。
路人丙返回
路人乙返回
路人甲返回
5.执行顺序:
1.row1.process_request(self,req)--->row2.process_request(self,req)...
#如果有process_request函数有返回值,则不继续进行。
2.row1.process_view(self,...)--->row2.process_view(self,...)....
3.views.函数
4.row1.process_response(self,req,response)-->row2.process_response(self,req,response)...
5.如果views.函数 在执行中报错了,才会执行的中间件函数:
def process_exception(self,req,exception):
print('错误提示信息')
#感觉可以用于设置一个精美的404界面
第五课 缓存
1.6种缓存模式:
开发调试(不做任何缓存,只是开启)
内存
文件
数据库
Memcache缓存(python-memcached模块)
Memcache缓存(pylibmc模块,只是与上面换了个模块而已)
2.配置:
1.开发调试:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',# 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存达最大后,剔除缓存比例,即:1/CULL_FREQUENCY(默认3)
},
'KEY_PREFIX': '', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}
2.内存:
# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
# 注:其他配置同开发调试版本
3.文件:
# 此缓存将内容保存至文件
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
# 注:其他配置同开发调试版本
4.5.6.略
3.实例(文件):
1.在项目目录下建立cache目录
2.在settings下加入配置代码:
CACHES={
'default':{
'BACKEND':'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION':os.path.join(BASE_DIR,'cache')
}
}
3.在urls.py下增加路径:
path('cache/', views.cache),
4.在views.py下:
1.作用于整个函数的缓存,前端只要调用就使用缓存,给函数加装饰器:
from django.views.decorators.cache import cache_page
@cache_page(10) #对函数进行缓存,10秒钟失效,只要调用就用缓存
def cache(req):
import time
ctime=time.time()
return render(req,'cache.html',{'ctime':ctime})
2.局部使用缓存(适用范围更广一些)只引入模块,不加装饰器:
from django.views.decorators.cache import cache_page
def cache(req):
import time
ctime=time.time()
return render(req,'cache.html',{'ctime':ctime})
在前端html文件中:#############最常用
{% load cache %}
<html>
....
{% cache 10 c1 %} #10秒钟失效
<h1>{{ ctime }}</h1>
{% endcache %}
...
</html>
3.整个全站设置缓存,使用中间件(几乎没有应用场景)
第六课 信号(作用于函数内部方法的’装饰器‘):
略
第七课 Form组件验证(用于注册,比modelform定制性强):
1.templates目录下新建fm.html文件:
...
<style>
.c1{
background-color: blue;
}
</style>
...
<form action="/fm/" method="post">
{% csrf_token %}
<p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
<p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
<p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
<p><input type="submit" value="提交"></p>
</form>
...
2.views.py下:
from django.forms import Form
from django.forms import fields
from django.forms import widgets
class FM(Form):
user=fields.CharField(error_messages={'required':'用户名不能为空'})
#变量名自动匹配前端传过来的name值
pwd=fields.CharField(
max_length=12,
min_length=6,
error_messages={'required':'密码不能为空','max_length':'密码长度不能大于12','min_length':'密码长度不能小于6'},
widget=widgets.PasswordInput(attrs={'class':'c1'})
)
email=fields.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误!'})
def fm(req):
if req.method=='GET':
obj=FM()
return render(req,'fm.html',{'obj':obj})
elif req.method=='POST':
#获取用户所有数据
#每条数据的请求验证
#成功:获取所有正确的信息
#失败:显示错误信息
obj=FM(req.POST)
r1=obj.is_valid()
print(r1)#数据是否符合要求,成功:True 失败:False
if r1:
print(obj.is_valid())
else:
print(obj.errors)
return render(req,'fm.html',{'obj':obj})
第二十二章 Django会话与表单验证第一课 模板回顾1.基本操作def func(req):return render(req,'index.html',{'val':[1,2,3...]}#index.html<h1>{{val.0}}2.继承:一个html页面只能继承一个模板extends 'layout.html'{{ block xxx}}...{{endblock}}3.组件:{{include tag.html}}4.自定义函数:simple_tag:任意参数,不能用于条件。 filter: 参数限制,不能加空格,可以用于条件判断。第二课 session1.session的原理:Cookie是保存在用户客户端的键值对Session是保存在服务器端的键值对实例:def login(req):if req.method=="GET":return render(req,'login.html')elif req.method=="POST":u=req.POST.get('username')p=req.POST.get('pwd')if u=='root' and p=='123':#1.生成随机字符串#2.写到用户浏览器cookie#3.保存到session#4.在随机字符串对应的字典中设置相关内容...#1/2/3/4合并为 设置session值req.session['username']=ureq.session['is_login']=Trueif req.POST.get('rmb',None)=='1':#超时时间,10秒req.session.set_expiry(10)return redirect('/index/')
else:return render(req,'login.html')def index(req):#session获取值if req.session.get('is_login'):return render(req,'index.html',{'username':req.session['username']})else:return HttpResponse('滚')运行Session之前,需要在命令行输入:python manage.py makemigrationspython manage.py migrate2.session的基本操作:session获取值:req.session['k1']# 会报错req.session.get('k1',None) #不会报错session设置值:req.session['k1']='v1'req.session.setdefault('k1',123)#存在则不设置session删除:del req.session['k1']session注销(退出登录):后台views代码:def logout(req):req.session.clear()return redirect('/login/')前端代码:<a href="/logout">注销</a>session设置超时时间:req.session.set_expiry(10)#10秒3.session的配置(setting.py):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,默认修改之后才保存(默认)第三课 CSRF1.基于form表单的post加CSRF:前端代码:<form action="/fm/" method="post">{% csrf_token %}....<p><input type="submit" value="提交"></p></form>2.给所有Ajax加CSRF的配置:前端代码:<script src="/static/jquery-3.2.1.js"></script><script>$(function () {$.ajaxSetup({data: {csrfmiddlewaretoken: '{{ csrf_token }}' }});$('#btn').click(function () {$.ajax({url:'/login/',type:'POST',data:{'user':'root','pwd':'123'},suceess:function (arg) {
}})});$('#btn2').click(function () {$.ajax({url:'/login/',type:'POST',data:{'user':'root','pwd':'123'},suceess:function (arg) {}})})})</script>第四课 中间件(管道)1.在项目下建立目录:Middle 并在目录下创建py文件:m1.pym1.py中的代码:from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponseclass row1(MiddlewareMixin):def process_request(self,req):print('路人甲')# return HttpResponse('一旦process_request有返回值就截住啦!')def process_view(self, request, callback, callback_args, callback_kwargs):print("中间件1view")def process_response(self,req,response):print('路人甲返回')return responseclass row2(MiddlewareMixin):def process_request(self,req):print('路人乙')def process_view(self, request, callback, callback_args, callback_kwargs):print("中间件2view")def process_response(self,req,response):print('路人乙返回')return responseclass row3(MiddlewareMixin):def process_request(self,req):print('路人丙')def process_view(self, request, callback, callback_args, callback_kwargs):print("中间件3view")def process_response(self,req,response):print('路人丙返回')return response2.在setting.py文件中MIDDLEWARE 列表中加入代码:MIDDLEWARE = [....'Middle.m1.row1','Middle.m1.row2','Middle.m1.row3',]3.views.py中增加函数:def test(req):print('路人丁--》没带钱。')return HttpResponse('ok')4.加入url.py路径后,访问路径,运行输出:路人甲路人乙路人丙中间件1view中间件2view中间件3view路人丁--》没带钱。路人丙返回路人乙返回路人甲返回5.执行顺序:1.row1.process_request(self,req)--->row2.process_request(self,req)...#如果有process_request函数有返回值,则不继续进行。2.row1.process_view(self,...)--->row2.process_view(self,...)....3.views.函数4.row1.process_response(self,req,response)-->row2.process_response(self,req,response)...5.如果views.函数 在执行中报错了,才会执行的中间件函数:def process_exception(self,req,exception):print('错误提示信息')#感觉可以用于设置一个精美的404界面第五课 缓存1.6种缓存模式:开发调试(不做任何缓存,只是开启)内存文件数据库Memcache缓存(python-memcached模块)Memcache缓存(pylibmc模块,只是与上面换了个模块而已)2.配置:1.开发调试:CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache',# 引擎 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 3, # 缓存达最大后,剔除缓存比例,即:1/CULL_FREQUENCY(默认3) }, 'KEY_PREFIX': '', # 缓存key的前缀(默认空) 'VERSION': 1, # 缓存key的版本(默认1) 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】)}}2.内存:# 此缓存将内容保存至内存的变量中# 配置:CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake',}}
# 注:其他配置同开发调试版本3.文件:# 此缓存将内容保存至文件# 配置:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache','LOCATION': '/var/tmp/django_cache',}}# 注:其他配置同开发调试版本4.5.6.略3.实例(文件):1.在项目目录下建立cache目录2.在settings下加入配置代码:CACHES={'default':{'BACKEND':'django.core.cache.backends.filebased.FileBasedCache','LOCATION':os.path.join(BASE_DIR,'cache')}}3.在urls.py下增加路径:path('cache/', views.cache),4.在views.py下:1.作用于整个函数的缓存,前端只要调用就使用缓存,给函数加装饰器:from django.views.decorators.cache import cache_page@cache_page(10) #对函数进行缓存,10秒钟失效,只要调用就用缓存def cache(req):import timectime=time.time()return render(req,'cache.html',{'ctime':ctime})2.局部使用缓存(适用范围更广一些)只引入模块,不加装饰器:from django.views.decorators.cache import cache_pagedef cache(req):import timectime=time.time()return render(req,'cache.html',{'ctime':ctime})在前端html文件中:#############最常用{% load cache %}<html>....{% cache 10 c1 %} #10秒钟失效<h1>{{ ctime }}</h1>{% endcache %}...</html>3.整个全站设置缓存,使用中间件(几乎没有应用场景)第六课 信号(作用于函数内部方法的’装饰器‘):略第七课 Form组件验证(用于注册,比modelform定制性强):1.templates目录下新建fm.html文件:...<style>.c1{background-color: blue;}</style>...<form action="/fm/" method="post">{% csrf_token %}<p>{{ obj.user }}{{ obj.errors.user.0 }}</p><p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p><p>{{ obj.email }}{{ obj.errors.email.0 }}</p><p><input type="submit" value="提交"></p></form>...2.views.py下:from django.forms import Formfrom django.forms import fieldsfrom django.forms import widgetsclass FM(Form):user=fields.CharField(error_messages={'required':'用户名不能为空'})#变量名自动匹配前端传过来的name值pwd=fields.CharField(max_length=12,min_length=6,error_messages={'required':'密码不能为空','max_length':'密码长度不能大于12','min_length':'密码长度不能小于6'},widget=widgets.PasswordInput(attrs={'class':'c1'}))email=fields.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误!'})def fm(req):if req.method=='GET':obj=FM()return render(req,'fm.html',{'obj':obj})elif req.method=='POST':#获取用户所有数据#每条数据的请求验证#成功:获取所有正确的信息#失败:显示错误信息obj=FM(req.POST)r1=obj.is_valid()print(r1)#数据是否符合要求,成功:True 失败:Falseif r1:print(obj.is_valid())else:print(obj.errors)return render(req,'fm.html',{'obj':obj})