python_way day19 HTML-day5 (form表单验证,CSRF,cookie,session,缓存)
python-way day19
1. dJango的form表单验证
2.CSRF 跨站请求伪造
3.cookie,session
4.缓存
一,django表单验证功能
1、django验证基础:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>django form</title> </head> <body> <div> <input type="text" placeholder="用户名" name="user"> </div> <div> <input type="password" placeholder="密码" name="password"> </div> <input type="button" value="提交"> </body> <script src="/statics/js/jquery-3.1.0.min.js"></script> <script src="/statics/js/my_js.js"></script> <script> $("div input").VelidForm("input[type=button]"); //使用jquery extend //把所有div下面的input作为筛选传过去,并且把点击的按钮作为参数传过去 </script> </html>

(function ($) {
$.fn.extend({
VelidForm: function (button) { //扩展方法
var inps = this; //所有的用户输入框
$(button).click(function () { //点击事件绑定
var input_dict = {}; //定义一个空字典
$(inps).each(function () { //循环所有input
var v = $(this).val(); //获取value
var k = $(this).attr("name"); //获取key
input_dict[k] = v; //给字典赋值
});
$.ajax({ //发送ajax请求
url: "/django_form/",
type: "POST",
data: input_dict,
dataType: "json",
//回调函数
success: function (data) {
//ajax提交成功调用这个函数
},
error:function () {
//ajax失败自动调用这个函数
}
})
})
}
});
})(jQuery);
#定义验证规则 from django import forms #需要倒入继承django给我们提供的forms class LoginForm(forms.Form): user = forms.CharField(required=True) #required = True 输入不能为空 password = forms.CharField(required=True) def django_form(request): if request.method == "POST": obj = LoginForm(request.POST) #request.POST 里面有用户输入的所有信息 ret = obj.is_valid() #这样就验证了用户输入是否为空 print(ret) #这样就能看到了返回值:True False
if ret:
print(obj.clean()) #拿到正确的输入值
else:
print(obj.errors) #拿到错误值
return render(request, "django_form.html")
只要有一项没有填写内容,ret就是False: 并且obj.errors 会把错误获取到 (password没有填写内容)
注意:匹配规则名称要统一
views:
django_form.html
2、获取错误信息
首先我们看到了我们获取到的错误信息时一个<ul><li>的类型,那么就说明了这个error里面应该有一个str方法,这个方法输出的就是这个类型,那我们来来看一下这个error
的类型,看看他的本质!
是一个错误字典类型:

else: from django.forms.utils import ErrorDict print(type(obj.errors)) return render(request, "django_form.html") ==================================== class ErrorDict(dict): """ A collection of errors that knows how to display itself in various formats. The dictionary keys are the field names, and the values are the errors. """ def as_data(self): return {f: e.as_data() for f, e in self.items()} def as_json(self, escape_html=False): return json.dumps({f: e.get_json_data(escape_html) for f, e in self.items()}) def as_ul(self): if not self: return '' return format_html( '<ul class="errorlist">{}</ul>', format_html_join('', '<li>{}{}</li>', ((k, force_text(v)) for k, v in self.items())) ) def as_text(self): output = [] for field, errors in self.items(): output.append('* %s' % field) output.append('\n'.join(' * %s' % e for e in errors)) return '\n'.join(output) def __str__(self): return self.as_ul()
可以看到里面有很多的方法,默认str输出的是al_ul,如果我们想要as_json,我们也可以获取到
1 2 3 4 5 6 7 8 9 | def django_form(request): if request.method = = "POST" : obj = LoginForm(request.POST) #request.POST 里面有用户输入的所有信息 ret = obj.is_valid() #这样就验证了用户输入是否为空 if ret: print (obj.clean()) else : print (obj.errors.as_json()) #这样我们就获得了json格式的错误提示 return render(request, "django_form.html" ) |
#定义验证规则 from django import forms #需要倒入继承django给我们提供的forms import json class LoginForm(forms.Form): user = forms.CharField(required=True) #required = True 输入不能为空 password = forms.CharField(required=True) def django_form(request): if request.method == "POST": obj = LoginForm(request.POST) #request.POST 里面有用户输入的所有信息 ret = obj.is_valid() #这样就验证了用户输入是否为空 result = {"status":False,"message":None} if ret: result["status"] = True print(obj.clean()) else: error_str = obj.errors.as_json() print(obj.errors.as_json()) result["message"] = json.loads(error_str) return HttpResponse(json.dumps(result)) return render(request, "django_form.html")
前端js

(function ($) { $.fn.extend({ VelidForm: function (button) { //扩展方法 var inps = this; //所有的用户输入框 $(button).click(function () { //点击事件绑定 var input_dict = {}; //定义一个空字典 $(inps).each(function () { //循环所有input var v = $(this).val(); //获取value var k = $(this).attr("name"); //获取key input_dict[k] = v; //给字典赋值 }); $('.error-msg').remove(); $.ajax({ url: "/django_form/", type: "POST", data: input_dict, dataType: "json", //这样指定了数据的格式是json //回调函数 success: function (data) { //ajax提交成功调用这个函数 if(data.status){ location.href = "/index/"; }else{ $.each(data.message, function (k,v) { //拿到的是一个字典,循环这个字典,获取它的k和v //{"user": [{"code": "required", "message": "This field is required."}], // "password": [{"code": "required", "message": "This field is required."}]} console.log(k,v[0].message); //获取message内容 var tag = document.createElement('span'); //dom创建标签 tag.className = 'error-msg'; //添加样式 tag.innerText = v[0].message; //插入内容 // $('inps[name="' + k + '"]').after(tag) 字符串的拼接(字符窜拼接的例子,这里没有用到) $(inps).each(function () { //循环传过来的input标签 if($(this).attr("name") == k ){ //如果这个当前循环到的标签的name = 上面我们循环的k则在他后面添加一个错误信息 $(this).after(tag) } }) }); // JSON.parse(data) 这样㛑可以转换成dict格式 } }, error:function () { //ajax失败自动调用这个函数 } }) }) } }); })(jQuery);
3、自定义message信息
1 2 3 4 5 6 7 8 9 10 11 | #定义验证规则 from django import forms #需要倒入继承django给我们提供的forms import json class LoginForm(forms.Form): user = forms.CharField(required = True , error_messages = { 'required' : '用户名不能为空' }) #required = True 输入不能为空 password = forms.CharField(required = True ,min_length = 6 ,max_length = 10 , error_messages = { 'required' : '密码不能为空' , 'min_length' : "不能小于6位" , 'max_length' : "不能大于10位" }) num = forms.IntegerField(error_messages = { 'invalid' : "必须输入数字" , 'required' : "不能为空" }) #因为输入不规范, # 所以我们使用了一个规定好的key作为错误提示的ksy invalid,只要有和forms定义的类型不符合的都可以用invalid url = forms.URLField(error_messages = { "required" : "url不能为空" , "invalid" : "请输入url格式" }) email = forms.EmailField(error_messages = { "required" : "邮箱不能为空" , "invalid" : "请输入邮箱格式" }) |
4、自定义验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from django.forms import ValidationErrordef mobile_validate(value): """ 自定制手机格式验证 """ mobile_re = re. compile (r '^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$' ) if not mobile_re.match(value): raise ValidationError( '手机号码格式错误' ) #定义验证规则 from django import forms #需要倒入继承django给我们提供的forms import json class LoginForm(forms.Form): user = forms.CharField(required = True , error_messages = { 'required' : '用户名不能为空' }) #required = True 输入不能为空 password = forms.CharField(required = True ,min_length = 6 ,max_length = 10 , error_messages = { 'required' : '密码不能为空' , 'min_length' : "不能小于6位" , 'max_length' : "不能大于10位" }) phone = forms.CharField(validators = [mobile_validate,],error_messages = { 'required' : '手机号不能为空' })<br> #自定义一个方法 mobile_validate 然后放到 forms.CharField中,使用一个列表括起来。后面还可以增加错误信息提示。 |
5、使用form标签提交表单验证:
本质上form和ajax提交验证,后台是没有却别的,都是从POST请求中获取提交的内容,只不过我们返回时form需要返回一个页面,而ajax是返回的一个字符串,因为ajax不刷新页面。
这里form就可以做到既做到验证,又帮助你生成标签
例子:
还是使用这个forms验证的类
#定义验证规则 from django import forms #需要倒入继承django给我们提供的forms import json class LoginForm(forms.Form): user = forms.CharField(required=True, error_messages={'required':'用户名不能为空'}) #required = True 输入不能为空 password = forms.CharField(required=True,min_length=6,max_length=10, error_messages={'required':'密码不能为空','min_length':"不能小于6位",'max_length':"不能大于10位"}) num = forms.IntegerField(error_messages={'invalid':"必须输入数字",'required':"不能为空"})#因为输入不规范, # 所以我们使用了一个规定好的key作为错误提示的ksy invalid,只要有和forms定义的类型不符合的都可以用invalid url = forms.URLField(error_messages={"required":"url不能为空","invalid":"请输入url格式"}) email = forms.EmailField(error_messages={"required":"邮箱不能为空","invalid":"请输入邮箱格式"}) phone = forms.CharField(validators=[mobile_validate,],error_messages={'required':'手机号不能为空'})
def my_form(request): if request.POST: #提交表单是POST请求,如果是post请求则到这里 objPost = LoginForm(request.POST) ret = objPost.is_valid() if ret: #所有的用户输入信息验证成功后 print(objPost.clean()) # else: #这里是展示错误时使用的else,所以不用就给注释了。 # error_dict = objPost.errors.items() #这里面封装中所有的错误信息ErrorDict # for k, v in error_dict: # print(k,v) 这里能看到错误的项目和错误的消息ul # print(objPost.errors['user'][0]) #这里一次提交可能有很多的错误信息,我们只返回第一个错误信息 ,我们只要把这些错误信息传导前面去就可以了 # print(objPost.errors['phone'][0]) # print(objPost.errors['email'][0]) return render(request, "form.html", {"obj1": objPost}) #此时的objPost里面封装了所有用户提交的数据 else: #get请求,就给用户返回一个干净的页面 objGet = LoginForm() return render(request, "form.html",{"obj1":objGet}) #此时的obj1创建form是不带参数的用户输入
前端html内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>django form< / title> <link href = "/statics/css/my_css.css" / > < / head> <body> <form action = "/form/" method = "POST" > { # 这里就需要form提交表单了#} <div> {{ obj1.user }} { # 1、第一次get请求时这里是get请求时接收到的后端发来的objGet = LoginForm(),并且form自动给我们创建了表单了#} { # 2、post请求时我们这里就获得了objPost = LoginForm(request.POST) ,这里面封装这用户之前填写的内容,和错误提示#} <span>{{ obj1.errors.user. 0 }}< / span> { # 这里就是获取错误提示,我们把所有的消息都传过来了,使用.errors就可以获取到所有的错误信息,.user就是指拿到user的信息,0就是错误信息的第一个内容#} < / div> <div> {{ obj1.password }} <span>{{ obj1.errors.password. 0 }}< / span> < / div> <div> {{ obj1.num }} <span>{{ obj1.errors.num. 0 }}< / span> < / div> <div> {{ obj1.url }} <span>{{ obj1.errors.url. 0 }}< / span> < / div> <div> {{ obj1.email }} <span>{{ obj1.errors.email. 0 }}< / span> < / div> <div> {{ obj1.phone }} <span>{{ obj1.errors.phone. 0 }}< / span> < / div> < input type = "submit" value = "提交" > < / form> < / body> < / html> |
6、使用form标签提交表单验证补充 -- 设置生成标签的类型和样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django import forms #需要倒入继承django给我们提供的forms import json class LoginForm(forms.Form): user = forms.CharField(required = True , error_messages = { 'required' : '用户名不能为空' }) #required = True 输入不能为空 password = forms.CharField(required = True ,min_length = 6 ,max_length = 10 , error_messages = { 'required' : '密码不能为空' , 'min_length' : "不能小于6位" , 'max_length' : "不能大于10位" }) text = forms.CharField(widget = forms.Textarea(attrs = { 'placeholder' : "备注" }),error_messages = { 'required' : "备注不能为空" }) # widget=forms.Textarea 生成什么标签,attrs={'placeholder':"备注"}) 设置样式 adder_choices = { ( 0 , '上海' ), ( 0 , '北京' ), } addr = forms.IntegerField(widget = forms.Select(choices = adder_choices)) #显示是北京,上海,但是真实提交过来的数据是0和1 #设置select 下拉框标签 |
二、CSRF 跨站请求伪造
全局:
中间件
1 | django.middleware.csrf.CsrfViewMiddleware |
局部:
- @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
- @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:
1 | from django.views.decorators.csrf import csrf_exempt,csrf_protect |
当第一次访问页面的时候后台给了用户一个html页面,这个时候暗地里还给用户发了一个Token,用户提交数据的时候我会查看一下用户是否有这个Token,如果没有我就会认为用户曾近没有来过,
没有来过给我提交的消息我一律不收,如果有,我才收。
1、如果这一项打开了,就证明了启用了CSRF功能
2、在form标签里面增加一个"内兜",让后端可以把Token放进去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <body> <form action = "/form/" method = "POST" > { % csrf_token % } < - - - - - - 就是这里,添加上这句话就可以了 <div> {{ obj1.user }} <span>{{ obj1.errors.user. 0 }}< / span> < / div> <div> {{ obj1.password }} <span>{{ obj1.errors.password. 0 }}< / span> < / div> <div> {{ obj1.num }} <span>{{ obj1.errors.num. 0 }}< / span> < / div> <div> {{ obj1.url }} <span>{{ obj1.errors.url. 0 }}< / span> < / div> < input type = "submit" value = "提交" > < / form> < / body> |
3、后端还需要一个最重要的东西
1 | return render(request, "csrf.html" ) |
需要render来渲染才能在前段生成input标签。
4、提交数据查看效果
这串字符串就是后端给的Token
5、放置位置:
一个是以Token的形式放在了input的表单中,这里是用于form表单提交使用;
第二是放在了cookie里,这里是用于ajax这种不把所有页面都提交的形式验证的。
6、ajax 提交表单,csrf配置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>csrf</title> </head> <body> <form action="/csrf/" method="POST"> {% csrf_token %} <input type="text" name="v" /> <input type="submit" value="提交" /> </form> <input type="button" value="Ajax提交" onclick="DoAjax();" /> <script src="/statics/js/jquery-3.1.0.min.js"></script> //1、引入扩展 <script src="/statics/js/jquery.cookie.js"></script> //还需要引入cookie扩展 <script> //2、去cookie中取token var csrftoken = $.cookie("csrftoken"); //从cookie中获取到csrftoken,这个是一个jquery扩展 function csrfSafeMethod(method) { return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } //3、将请求头中放入从cookie中取出来的token $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain){ xhr.setRequestHeader("X-CSRFToken", csrftoken); //这是把csrftoken放到请求头里面 } } }); function DoAjax() { $.ajax({ url:'/csrf/', type: "POST", data:{"k1":"v1"}, success: function (data) { console.log(data) } }) } </script> </body> </html>
7、CSRF使用范围: 全局和局部
- @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
- @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
1 2 3 4 5 6 7 8 | from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt #加上这句,即使在setting里面开放使用,这个views中的csrf函数也不使用 def csrf(request): if request.method = = "POST" : text = request.POST.get( "v" , None ) ajax = request.POST.get( "k1" , None ) print (text, ajax) return render(request, "csrf.html" ) |

<form action="/csrf/" method="POST"> {# {% csrf_token %}#} 这里给注释掉了, <input type="text" name="v" /> <input type="submit" value="提交" /> </form> 这个表单就可以不被CSRF管制了
三、cookie && session
cookie 客户端保存用户信息的位置。
session 在服务器上对应着cookie保存的信息位置就是session
(session可以保存在缓存里,数据库里,文件里,session依赖cookie)
1、cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 | def layout(request): client_cookie = request.COOKIES #获取客户端的cookie print (client_cookie) obj = render(request, "layout.html" ) obj.set_cookie( "k2" , "v2" ,path = '/layout/' ) #给客户端设置cookie return obj<br> <br> #set_cookie中还有很多的参数:max_age = None, 多少秒后失效; <br> #expires = None 什么时候以后失效 ;<br> # path = "/"设置的cookie在哪个url下可用;<br> # domain=Nome 域名,None跨域名不能访问,当前域名<br> #secure= False, https是否可以传输 True是支持https<br> #httponly = False,如果为True 只能在http协议中传输,别的方式都获取不到的。 <br> #如果 path = “/layout/” 下面的;layout1就看不到设置的k2,v2这个 cookie def layout1(request): client_cookie = request.COOKIES #获取客户端的cookie print (client_cookie) obj = render(request, "layout1.html" ) return obj |
使用cookie实现用户登录
1 2 3 4 5 6 7 8 9 10 11 12 13 | def login(request):<br> """<br>用户登陆view函数<br>""" if request.method = = "POST" : #如果用户是POST请求 u = request.POST.get( "username" , None ) #获取用户输入信息 p = request.POST.get( "password" , None ) if u = = "han" and p = = "123" : #如果用户输入信息正确 print ( "ok" ) red = redirect( "/layout/" ) red.set_cookie( "username" , u) #使用redirect设置cookie return red #让用户跳转 else : return render(request, ";login.html" ) #否则还停留在当前页面 else : return render(request, "login.html" ) #如果用户是get请求,直接返回当前登陆页面 |
1 2 3 4 5 6 7 | def layout(request):<br> """<br>登陆成功跳转后的页面<br>""" client_username = request.COOKIES.get( "username" ) #获取客户端的cookie print (client_username) if client_username: #判断cookie中的username值,可以随意操作 return render(request, "layout.html" ) #正确就跳转 obj = render(request, "login.html" ) #如果不登录直接访问就让用户跳转到登陆页面 return obj |
问题来了:
如果用cookie,你所有存放的敏感的信息都是可见的了。所以我们就要选择更好的方法。
2、session
1 2 3 4 5 6 7 8 | def session_login(request): if request.method = = "POST" : u = request.POST.get( "username" , None ) p = request.POST.get( "password" , None ) if u = = "han" and p = = "123" : request.session[ 'user' ] = u #设置session字符串 return redirect( '/session_index/' ) return render(request, "session_login.html" ) |
1 2 3 4 5 | def session_index(request): if request.session.get( 'user' , None ): #获取session消息 if request.session.get( 'user' ) = = "han" : return render(request, "session_index.html" ) return render(request, "session_login.html" ) |
django默认给我们提供了session的方法,其他的web框架,可能没有这个方法,我们需要自己写。
原理就是在用户登陆成功以后我们生成一段随机字符串,这个字符串一个以session的形式给客户端的阅览器色cookie中设置上,一个是自己保存,并且我们还可以把自己保存的这个字符串当成key,value
可以是用户的很多信息。这样用户拿到的那串session随机字符串根本就不知道是干什么的.
在我们登陆时候,session在设置时需要往默认的数据库中插人值,这个错误就是因为没有django_session的表,我们需要执行一下makemigrations migrate,让django创建一下这个表
设置好以后我们再登陆,这样就生成了。

def auth(func): """ 访问主页的装饰器 func就是传过来的 session_index 在return func这个函数之前我们做了一个验证的操作 如果user中有值我们才去执行index函数,如果没有通过就直接跳转到session_login这个函数中了。 """ def inner(request): if request.session.get('user',None): return func(request) else: return redirect('/session_login/') return inner @auth def session_index(request): user = request.session.get('user') == "han" return render(request,"session_index.html") def session_login(request): if request.method == "POST": u = request.POST.get("username", None) p = request.POST.get("password", None) if u == "han" and p == "123": request.session['user'] = u return redirect('/session_index/') return render(request,"session_login.html") @auth def session_logout(request): """ 注销用户:通过装饰器检查如果用户是登陆状态,则执行这个里的代码,这里删除完用户存在session中的信息后,直接跳转到登陆页面 """ del request.session['user'] return render(request,"session_login.html")
3、session 存放位置:
Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:
- 数据库(默认)
- 缓存
- 文件
- 缓存+数据库
- 加密cookie
Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 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,默认修改之后才保存(默认) b. 使用 def index(request): # 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] #只把session_key 中 的k1的值删除,不用想当前session_kay的其他键值对 # 所有 键、值、键值对 (批量操作) request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() #django数据库中的过期session不会自定删除,这个方法就是将过去的全部删除 # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") # session_key = request.session.session_key 这里是把这个session_key 对应的所有值全部删除

a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 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,默认修改之后才保存 b. 使用 同上

a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T 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,默认修改之后才保存 b. 使用 同上

数据库用于做持久化,缓存用于提高效率 a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 b. 使用 同上

a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 b. 使用 同上
缓存的配置文件需要和CASHE选项配合使用
更多内容 django_session官方 和 这里
四、缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。
Django中提供了6种缓存方式:
- 开发调试
- 内存
- 文件
- 数据库
- Memcache缓存(python-memcached模块)
- Memcache缓存(pylibmc模块)
1、开发调试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # 此为开始调试用,实际内部不做任何操作 # 配置: 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】) } } # 自定义key def default_key_func(key, key_prefix, version): """ Default function to generate keys. Constructs the key used by all other methods. By default it prepends the `key_prefix'. KEY_FUNCTION can be used to specify an alternate function with custom key making behavior. """ return '%s:%s:%s' % (key_prefix, version, key) def get_key_func(key_func): """ Function to decide which key function to use. Defaults to ``default_key_func``. """ if key_func is not None : if callable (key_func): return key_func else : return import_string(key_func) return default_key_func |
2、内存
1 2 3 4 5 6 7 8 9 10 | # 此缓存将内容保存至内存的变量中 # 配置: CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.locmem.LocMemCache' , 'LOCATION' : 'unique-snowflake' , } } # 注:其他配置同开发调试版本 |
3、文件
1 2 3 4 5 6 7 8 9 10 | # 此缓存将内容保存至文件 # 配置: CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.filebased.FileBasedCache' , 'LOCATION' : '/var/tmp/django_cache' , } } # 注:其他配置同开发调试版本 |
4、数据库
1 2 3 4 5 6 7 8 9 10 11 | # 此缓存将内容保存至数据库 # 配置: CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.db.DatabaseCache' , 'LOCATION' : 'my_cache_table' , # 数据库表 } } # 注:执行创建表命令 python manage.py createcachetable |
5、Memcache缓存(python-memcached模块)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # 此缓存使用python-memcached模块连接memcache CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache' , 'LOCATION' : '127.0.0.1:11211' , } } CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache' , 'LOCATION' : 'unix:/tmp/memcached.sock' , } } CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache' , 'LOCATION' : [ '172.19.26.240:11211' , '172.19.26.242:11211' , ] } } |
6、Memcache缓存(pylibmc模块)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # 此缓存使用pylibmc模块连接memcache CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.PyLibMCCache' , 'LOCATION' : '127.0.0.1:11211' , } } CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.PyLibMCCache' , 'LOCATION' : '/tmp/memcached.sock' , } } CACHES = { 'default' : { 'BACKEND' : 'django.core.cache.backends.memcached.PyLibMCCache' , 'LOCATION' : [ '172.19.26.240:11211' , '172.19.26.242:11211' , ] } } |
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步