python_way day19 HTML-day5 (form表單驗證,CSRF,cookie,session,緩存)

python-way day19 

1. dJango的form表單驗證css

2.CSRF 跨站請求僞造html

3.cookie,session前端

4.緩存python

 

 


 一,django表單驗證功能

一、django驗證基礎:jquery

<!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沒有填寫內容) web

注意:匹配規則名稱要統一ajax

views:數據庫

django_form.htmldjango

 

二、獲取錯誤信息json

首先咱們看到了咱們獲取到的錯誤信息時一個<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信息

三、自定義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":"請輸入郵箱格式"})

  

四、自定義驗證

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中,使用一個列表括起來。後面還能夠增長錯誤信息提示。

 

五、使用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 }}  
{#            一、第一次get請求時這裏是get請求時接收到的後端發來的objGet = LoginForm(),而且form自動給咱們建立了表單了#}
{#              二、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>

六、使用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 下拉框標籤

 


 

2、CSRF 跨站請求僞造

全局:

  中間件 

django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件。
  • @csrf_exempt,取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件。

注:

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

  

 

 當第一次訪問頁面的時候後臺給了用戶一個html頁面,這個時候暗地裏還給用戶發了一個Token,用戶提交數據的時候我會查看一下用戶是否有這個Token,若是沒有我就會認爲用戶曾近沒有來過,

沒有來過給我提交的消息我一概不收,若是有,我才收。

 

一、若是這一項打開了,就證實了啓用了CSRF功能

二、在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>

三、後端還須要一個最重要的東西

return render(request, "csrf.html")

須要render來渲染才能在前段生成input標籤。 

 

四、提交數據查看效果

這串字符串就是後端給的Token

五、放置位置:

一個是以Token的形式放在了input的表單中,這裏是用於form表單提交使用;

第二是放在了cookie裏,這裏是用於ajax這種不把全部頁面都提交的形式驗證的

六、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>
   
    //一、引入擴展
   <script src="/statics/js/jquery.cookie.js"></script>    //還須要引入cookie擴展
    <script> 

   //二、去cookie中取token
        var csrftoken = $.cookie("csrftoken");  //從cookie中獲取到csrftoken,這個是一個jquery擴展  
        function csrfSafeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
  //三、將請求頭中放入從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>

 

 

七、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

 


 

3、cookie && session

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

session 在服務器上對應着cookie保存的信息位置就是session

(session能夠保存在緩存裏,數據庫裏,文件裏,session依賴cookie)

 

一、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,你全部存放的敏感的信息都是可見的了。因此咱們就要選擇更好的方法。

 

二、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")
裝飾器實現用戶登錄和註銷的功能

 

三、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. 使用
 
    同上
二、緩存 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. 使用
 
    同上
三、文件 session

 

數據庫用於作持久化,緩存用於提升效率
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
 
b. 使用
 
    同上
四、數據庫 + 緩存 session
a. 配置 settings.py
     
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
 
b. 使用
 
    同上
五、加密 cookie session

 緩存的配置文件須要和CASHE選項配合使用

 

更多內容 django_session官方 和 這裏

 


 

4、緩存

因爲Django是動態網站,全部每次請求均會去數據進行相應的操做,當程序訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至內存或者memcache中,5分鐘內再有人來訪問時,則再也不去執行view中的操做,而是直接從內存或者Redis中以前緩存的內容拿到,並返回。

Django中提供了6種緩存方式:

  • 開發調試
  • 內存
  • 文件
  • 數據庫
  • Memcache緩存(python-memcached模塊)
  • Memcache緩存(pylibmc模塊)

 一、開發調試

# 此爲開始調試用,實際內部不作任何操做
    # 配置:
        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

二、內存

# 此緩存將內容保存至內存的變量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其餘配置同開發調試版本

三、文件

 # 此緩存將內容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其餘配置同開發調試版本

四、數據庫

   # 此緩存將內容保存至數據庫

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 數據庫表
            }
        }

    # 注:執行建立表命令 python manage.py createcachetable

五、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',
            ]
        }
    }

六、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',
            ]
        }
    }
相關文章
相關標籤/搜索