目錄html
裝飾器中加入funtools.wraps裝飾,可以保留函數的元數據(函數名、註釋)python
import functools def wrapper(f): @functools.wraps(f) def inner(*args,**kwargs): """ 這是inner函數 """ return f(*args, **kwargs) return inner def index(a1, a2): """ 這是index函數 """ return a1+a2 print(index.__name__) # index print(index.__doc__) # 這是index函數
請求進入Django前,有一個WSGI,可以接收請求,並將請求信息封裝。jquery
WSGI(Web Server Gateway Interface)就是一種規範,稱爲web服務網關接口,它定義了使用Python編寫的web應用程序與web服務器程序之間的接口格式,實現web應用程序與web服務器程序間的解耦。web
經常使用服務器:wsgiref/uwsgi ,本質是一個socket服務端。redis
過程:數據庫
客戶端發來一個請求,WSGI進行接收,而且將那個請求信息封裝,而後通過路由系統進行路由匹配,到達視圖views,進行業務邏輯處理,進行相應的orm操做以及模板的渲染。最後經過WSGI發送到客戶端。django
背景:前面學的django,雖然寫了不少頁面,可是用戶不用登錄都是能夠看全部網頁的,只要他知道網址就行,可是爲了本身的安全機制,須要要作驗證,訪問哪個網址,都要驗證用戶的身份,可是還有保證什麼呢,用戶登錄過以後,還要保證登錄了的用戶不須要再重複登錄,就可以訪問我網站的其餘的網址的頁面。可是http無狀態啊,怎麼保證這個事情呢?此時就要藉助cookie了。api
定義:cookie是瀏覽器的技術,Cookie具體指的是一段小信息,它是服務器發送出來存儲在瀏覽器上的一組組鍵值對,下次訪問服務器時瀏覽器會自動攜帶這些鍵值對,以便服務器提取有用信息。瀏覽器
cookie的工做原理:瀏覽器訪問服務端,帶着一個空的cookie,而後由服務器產生內容,瀏覽器收到響應後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣服務器就能經過Cookie的內容來判斷這個是「誰」了。緩存
Cookie的覆蓋 :若是服務器端發送重複的Cookie那麼會覆蓋原有的Cookie,例如客戶端的第一個請求服務器端發送的Cookie是:Set-Cookie: a=A;第二請求服務器端發送的是:Set-Cookie: a=AA,那麼客戶端只留下一個Cookie,即:a=AA。
Ctrl + Shift + del三個鍵來清除頁面緩存和cookie。
request.COOKIES['key'] request.COOKIES.get('key') # 經常使用
def index(request): #data = HttpResponse('字符串') #data = redirect('路徑') data = render(request, 'index.html') data.set_cookie('key',values) return data
參數:
key # 鍵 value='' # 值 max_age=None # 超時時間(失效時間),max_age=20意思是這個cookie20秒後就消失;參數是None ,會延續到瀏覽器關閉爲止。 expires=None # 超時時間,值是一個datetime類型的時間日期對象,到這個日期就失效的意思 path='/' # Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie能夠被任何url的頁面訪問;''只能被當前頁面訪問;'/index/'能被index以及其子路徑訪問。 domain=None #Cookie生效的域名 secure=False # 若是設置爲 True ,瀏覽器將經過HTTPS來回傳cookie。 httponly=False #只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)
document.cookie='key=yan;path=/' # js設置 $.cookie('key','yan', {path:'/'}) # jquery設置 注意:path不一樣會致使設置不一樣.
def logout(request): rep = redirect("/login/") rep.delete_cookie("user") # 刪除用戶瀏覽器上以前設置的usercookie值 return rep
示例:cookie版登錄校驗示例:
views.py文件:
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from app01 import models def login(request): """ 用戶登陸 :param request: :return: """ if request.method == 'GET': return render(request, 'login.html') # 獲取登陸的用戶名和密碼 user = request.POST.get('user') pwd = request.POST.get('pwd') # 判斷用戶名與密碼是否存在 user_obj = models.UserInfo.objects.filter(username=user,password=pwd).first() # 用戶登陸成功 if user_obj: data = redirect('/index/') data.set_cookie('xx', user) return data # 失敗 return render(request, 'login.html', {'error': '用戶名或密碼錯誤'}) def index(request): """ 登陸成功後跳轉的頁面 :param request: :return: """ user = request.COOKIES.get('xx') if not user: return render(request, 'login.html') return render(request, 'index.html', {'user': user}
用戶認證、投票、每頁默認顯示數據
背景:Cookie雖然在必定程度上解決了「保持狀態」的需求,可是因爲Cookie自己最大支持4096字節,以及Cookie自己保存在客戶端,可能被攔截或竊取,所以就須要有一種新的東西,它能支持更多的字節,而且他保存在服務器,有較高的安全性。這就是Session。
原理過程:session是一種存儲數據的方式,依賴於cookie。實現本質: 用戶向服務端發送請求,服務端作兩件事:一輩子成隨機字符串;二爲此用戶開闢一個獨立的空間來存放當前用戶獨有的值。視圖函數中的業務操做處理完畢後,給用戶響應,在響應時會將隨機字符串存儲到用戶瀏覽器的cookie中。
強調:session中的數據是根據用戶相互隔離.
request.session['k1'] = 123 request.session['k2'] = 456
request.session['k1'] request.session.get('k2') # 經常使用
#刪除值 del request.session['k1'] #django-session表裏面同步刪除 request.session.flush() # 清除session、cookie,多用於退出登陸
# 全部 鍵、值、鍵值對 request.session.keys() request.session.values() request.session.items() # 設置會話Session和Cookie的超時時間,可用於短信驗證 request.session.set_expiry(value) * 若是value是個整數,session會在些秒數後失效。 * 若是value是個datatime或timedelta,session就會在這個時間後失效。 * 若是value是0,用戶關閉瀏覽器session就會失效。 * 若是value是None,session會依賴全局session失效策略。 # 會話session的key session_key = request.session.session_key 獲取sessionid的值(隨機字符串)
默認存放在數據庫中
小系統:默認放在數據庫便可。
大系統:緩存(redis)
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = '/文件夾/'
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default' CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMem Cache', 'LOCATION': 'unique-snowflake',}}
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default' CACHES = { "default": {"BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "密碼",}}}
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即: sessionid=隨機字符串 SESSION_COOKIE_DOMAIN = None # api.baidu.com /www.baidu.com/ xxx.baidu.com 域名 SESSION_COOKIE_PATH = "/" # Session的cookie 保存的路徑 SESSION_COOKIE_HTTPONLY = True # 是否 Session的cookie只支持http傳輸,js不能修改 SESSION_COOKIE_AGE = 1209600 # Session的 cookie失效日期(默認2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時 SESSION_SAVE_EVERY_REQUEST = False # 是否每 次請求都保存Session,默認修改以後才保存
SESSION_COOKIE_AGE = 1209600 # Session的 cookie失效日期(2周)
示例:使用裝飾器,減小代碼重複。
views.py文件
def login(request): """ 用戶登陸 :param request: :return: """ if request.method == 'GET': return render(request, 'login.html') # 獲取登陸的用戶名和密碼 user = request.POST.get('user') pwd = request.POST.get('pwd') # 判斷用戶名於密碼是否存在 user_obj = models.UserInfo.objects.filter(username=user,password=pwd).first() # 用戶登陸成功 if user_obj: request.session['user_name'] = user_obj.username request.session['user_id'] = user_object.pk return redirect('/index/') return render(request, 'login.html', {'error': '用戶名或密碼錯誤'}) def auth(func): def inner(request, *args, **kwargs): name = request.session.get('user_name') if not name: return redirect('/login/') return func(request, *args, **kwargs) return inner @auth def index(request): """ 登陸成功後跳轉的頁面 :param request: :return: """ return render(request, 'index.html')
用戶認證、短信驗證過時、權限管理
cookie是存儲在客戶端瀏覽器上的鍵值對,發送請求時瀏覽器會自動攜帶. session是一種存儲數據方式,基於cookie實現,將數據存儲在服務端(django默認存儲到數據庫).其本質是: 用戶向服務端發送請求,服務端作兩件事:生成隨機字符 串;爲此用戶開闢一個獨立的空間來存放當前用戶獨有的值. 在空間中如何想要設置值: request.session['x1'] = 123 request.session['x2'] = 456 在空間中取值: request.session['x2'] request.session.get('x2') 視圖函數中的業務操做處理完畢,給用戶響應,在響應時會 將隨機字符串存儲到用戶瀏覽器的cookie中.