Django框架詳細介紹---cookie、session、自定義分頁

1.cookiehtml

  在HTTP協議介紹中提到,該協議是無狀態的,也就是每次請求都是獨立的,它的執行狀況和結果與前面的請求和以後的請求都無直接關係,它不會受前面的請求響應狀況直接影響,也不會直接影響後面的請求響應狀況,也就是說對於服務器而言,每次接收到的請求都是全新的,狀態能夠理解爲客戶端和服務器在會話中產生的數據,無狀態就是每次會話的數據都不會被保存,而在實際應用中某些特定的會話數據需保存下來,由此cookie就應運而生數據庫

  cookie具體指的事一段信息,是服務器發送過來存儲在瀏覽器上的一組鍵值對,再次訪問服務器時瀏覽器會自帶這些鍵值對,以便服務器提取須要的信息,例如進行身份驗證等django

  其實現原理很簡單,也就是有服務器產生鍵值對,瀏覽器收到後保存到本地,當瀏覽器再次訪問時,瀏覽器會自帶cookie發送給服務器,服務器對收到的鍵值對進行提取和校驗等操做瀏覽器

  通俗的說就是保存在客戶端/瀏覽器本地的鍵值對緩存

示例:瀏覽器中查看cookies安全

2.Django中實現cookie服務器

   1)設置cookiecookie

 
 
def login(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("pwd")
user_obj = models.User.objects.filter(username=username, password=password)
if user_obj:

url = request.GET.get("next")
print(url)
rep = redirect(url)
# 設置cookie 鍵 鍵值 加鹽處理 超時時間
rep.set_signed_cookie("login", "ok", salt="jiayanchuli", max_age=10)
return rep
else:
return render(request,
"login.html",
{"err_msg": "用戶名或密碼錯誤"})

return render(request, "login.html")

 參數session

  set_signed_cookie(self, key, value, salt='', **kwargs)框架

key              鍵
value=''           鍵值
max_age=None         超時時間
expires=None         超時時間(IE requires expires, so set it if hasn't been already.)
path='/'            Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie能夠被任何url的頁面訪問
domain=None                Cookie生效的域名
secure=False              https傳輸
httponly=False            只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)

   2)獲取cookie

def check_login(func):
    def warpper(request,*args,**kwargs):
        # 判斷請求裏面是否存在鍵值對                    默認拋出異常,需指定取不到值時爲空   加鹽處理
        login_flag = request.get_signed_cookie("login", default="", salt="jiayanchuli")
        if login_flag == "ok":
            # 已經登陸
            return func(request, *args, **kwargs)
        else:
            # 獲取當前訪問的URL
            url = request.path_info
            print("url = request.path_info", url)
            return redirect("/login/?next={}".format(url))
    return warpper

 參數

default                默認值
salt             加鹽處理    

 瀏覽器中查看超時時間

   3)刪除cookie

def logout(request):
    rep = redirect("/login/")
    # 退出時刪除以前在瀏覽器上面設置的cooks
    rep.delete_cookie("login")
    # print(rep.cookies.get("login"))

    return redirect("/login/")

 3.session

  cookie雖然在必定程度上解決了「保持狀態」的需求,但因爲Cookie自己最大支持4096字節,以及Cookie自己保存在客戶端,可能被攔截或竊取,所以須要相似於cookie的東西彌補這些不足,支持更多的字節,並保存在服務器,有較高的安全性,從而session就應運而生

  那麼,問題來了,基於HTTP協議的無狀態特徵,服務器根本就不知道訪問者是那個客戶端/瀏覽器,那麼以前提到的cookie就起到橋接的做用:

  能夠給每一個客戶端的Cookie分配一個惟一的id,這樣客戶端/瀏覽器在訪問時,經過cookie,服務器就知道來訪問的是誰,而後再根據不一樣的cookie的id,在服務器上保存一段時間的私密資料,如「帳號密碼」等

總結而言:cookie彌補了HTTP無狀態的不足,使得服務器端能夠區別出訪問者,但cookie以文本的形式保存在本地,自身安全性較低,因此就經過cookie識別不一樣的用戶,對應的在session裏保存私密的信息以及超過4096字節的文本

應該強調的是,以上描述的cookie和session是共通性的東西,不限於語言和框架

4.Django中session相關方法

# 獲取、設置、刪除Session中數據
request.session['key']
request.session.get('kkey',None)
request.session['key'] = value
request.session.setdefault('key',value) # 存在則不設置
del request.session['key']

# 全部 鍵、值、鍵值對
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

# 會話session的key
request.session.session_key

# 將全部Session失效日期小於當前日期的數據刪除
request.session.clear_expired()

# 檢查會話session的key在數據庫中是否存在
request.session.exists("session_key")

# 刪除當前會話的全部Session數據
request.session.delete()
  
# 刪除當前的會話數據並刪除會話的Cookie。
request.session.flush() 
    這用於確保前面的會話數據不能夠再次被用戶的瀏覽器訪問
    例如,django.contrib.auth.logout() 函數中就會調用它。

# 設置會話Session和Cookie的超時時間
request.session.set_expiry(value)
    * 若是value是個整數,session會在些秒數後失效。
    * 若是value是個datatime或timedelta,session就會在這個時間後失效。
    * 若是value是0,用戶關閉瀏覽器session就會失效。
    * 若是value是None,session會依賴全局session失效策略。

   1)解析流程

5.Django中實現session認證登陸

def check_login(func):
    def warpper(request, *args, **kwargs):
        # 判斷session是否存在鍵值對
        login_flag = request.session.get("login", None)
        if login_flag == "login":
            # 已經登陸
            return func(request, *args, **kwargs)
        else:
            # 獲取當前訪問的URL
            url = request.path_info
            print("url = request.path_info", url)
            return redirect("/login/?next={}".format(url))

    return warpper
認證裝飾器
def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("pwd")
        user_obj = models.User.objects.filter(username=username, password=password)
        if user_obj:
            url = request.GET.get("next")
            print(url)
            rep = redirect(url)
            # 認證成功,設置session
            # 1. 生成隨機字符串(口令),給瀏覽器返回
            # 2. 在服務端開闢一塊空間,用來保存對應的session數據(大字典)
            # 3. 在服務端開闢的空間中保存須要保存的鍵值對數據
            request.session["login"] = "login"
            request.session["username"] = username

            # request.session["pwd"] = password
            # 設置客戶端session保留時間
            request.session.set_expiry(0)

            return rep
        else:
            return render(request,
                          "login.html",
                          {"err_msg": "用戶名或密碼錯誤"})

    return render(request, "login.html")
認證視圖
def logout(request):
    request.session.flush()
    return redirect("/login/")
    # return render(request, "home.html")
刪除session

 6.Django中的session配置

1. 數據庫Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默認)

2. 緩存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() 

4. 緩存+數據庫
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

其餘公用設置項:
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,默認修改以後才保存(默認)

 7.Django視圖中使用裝飾器

  1)FBV中使用裝飾器

  與普通函數調用裝飾器的方法同樣,在函數前使用語法  @裝飾器名  調用

@check_login
def publisher_list(request):
    # 函數體

  2)CBV中使用裝飾器(三種方法)

from django.utils.decorators import method_decorator
# 導入相關CBV調用裝飾器須要的方法

   方法一:在CBV視圖的get或者post方法上調用

class Home(views.View):
    def dispatch(self, request, *args, **kwargs):
        return super(Home, self).dispatch(request, *args, **kwargs)
                
    @method_decorator(check_login)
    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        return render(request, "index.html")

  方法二:在dispatch方法上調用,CBV中首先執行的是該方法,因此至關於get和post都加上了裝飾器功能

class Home(views.View):
    @method_decorator(check_login)
    def dispatch(self, request, *args, **kwargs):
        return super(Home, self).dispatch(request, *args, **kwargs)
    
    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        return render(request, "index.html")

  方法三:在視圖類上直接調用,但必須傳入name關鍵字參數,指定是給哪一個方法調用

@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class Home(views.View):
    # 函數體,同時爲get和post加上裝飾器功能

  3)CSRF Token相關裝飾器(只能在dispatch上調用)

csrf_protect  爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置全局中間件
csrf_exempt   取消當前函數防跨站請求僞造功能,即使settings中設置了全局中間件
class Home(views.View):
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super(Home, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        return render(request, "index.html")

8.實現分頁

   1)自定義分頁

 待續

  2)Django內置分頁功能

 待續

相關文章
相關標籤/搜索