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>
django_form.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);            
my_js.js
#定义验证规则
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()
ErrorDict

 

可以看到里面有很多的方法,默认str输出的是al_ul,如果我们想要as_json,我们也可以获取到 

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);
前端 js - 使用默认的message信息

3、自定义message信息

#定义验证规则
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、自定义验证

from django.forms import ValidationError
def 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':'手机号不能为空'})
#自定义一个方法 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内容

<!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标签提交表单验证补充 -- 设置生成标签的类型和样式

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 跨站请求伪造

全局:

  中间件 

django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注:

from django.views.decorators.csrf import csrf_exempt,csrf_protect

  

 

 当第一次访问页面的时候后台给了用户一个html页面,这个时候暗地里还给用户发了一个Token,用户提交数据的时候我会查看一下用户是否有这个Token,如果没有我就会认为用户曾近没有来过,

没有来过给我提交的消息我一律不收,如果有,我才收。

 

1、如果这一项打开了,就证明了启用了CSRF功能

2、在form标签里面增加一个"内兜",让后端可以把Token放进去

<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、后端还需要一个最重要的东西

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提交" οnclick="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中设置了全局中间件。
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管制了
html代码中注释掉了token

 


 

三、cookie && session

cookie 客户端保存用户信息的位置。

session 在服务器上对应着cookie保存的信息位置就是session

(session可以保存在缓存里,数据库里,文件里,session依赖cookie)

 

1、cookie

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

  #set_cookie中还有很多的参数:max_age = None, 多少秒后失效;
#expires = None 什么时候以后失效 ;
# path = "/"设置的cookie在哪个url下可用;
# domain=Nome 域名,None跨域名不能访问,当前域名
#secure= False, https是否可以传输 True是支持https
#httponly = False,如果为True 只能在http协议中传输,别的方式都获取不到的。
#如果 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实现用户登录

def login(request):
"""
用户登陆view函数
""" 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请求,直接返回当前登陆页面  

 

def layout(request):
"""
登陆成功跳转后的页面
""" 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

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")

 

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. 使用
 
    同上
2、缓存 session
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. 使用
 
    同上
3、文件 session

 

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

 缓存的配置文件需要和CASHE选项配合使用

 

更多内容 django_session官方 和 这里

 


 

四、缓存

由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

Django中提供了6种缓存方式:

  • 开发调试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

 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】)
            }
        }


    # 自定义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、内存

# 此缓存将内容保存至内存的变量中
    # 配置:
        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、数据库

   # 此缓存将内容保存至数据库

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 数据库表
            }
        }

    # 注:执行创建表命令 python manage.py createcachetable

5、Memcache缓存(python-memcached模块)

# 此缓存使用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模块)

# 此缓存使用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',
            ]
        }
    }

 

  

  

 

  

  

 

转载于:https://www.cnblogs.com/python-way/p/5883517.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值