Django中間件 及 form 實現用戶登陸
阿新 • • 發佈:2017-12-31
mon bubuko 類型 end utils pda 返回 xxx elf
Django中間件 及 form 實現用戶登陸
- Form 驗證
- 密碼調用md5 加密存儲
- form.add_error("字段名", "錯誤信息") 自定義錯誤信息
- 裝飾器實現 用戶認證
中間件實現 用戶認證
中間件顧名思義,是介於request與response處理之間的一道處理過程,相對比較輕量級,並且在全局上改變django的輸入與輸出。因為改變的是全局,所以需要謹慎實用,用不好會影響到性能。
django默認的中間件在settings.py中
當用戶發起請求的時候會依次經過所有的的中間件,這個時候的請求時process_request,最後到達views的函數中,views函數處理後,在依次穿過中間件,這個時候是process_response,最後返回給請求者。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware' ,
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
自定義中間件
自己定義一個中間件,寫一個類,但是必須繼承MiddlewareMixin
中間件分為五種方法:
process_request(self,request) ***** 用於請求時過濾
process_response(self, request, response) ***** 用於相應時過濾 必須有返回值
process_view(self, request, callback, callback_args, callback_kwargs) *** 在執行完所有的process_request 後在回到 起點執行process_view ,然後在執行 視圖函數
process_exception(self, request, exception) *** 對異常信息捕捉
process_template_response(self,request,response) * 視圖函數返回的對象中間有render方法,就會被觸發
創建middlwares模塊
1.md.py內容中間件值
from django.conf import settings
from django.shortcuts import redirect
# 該 MiddlewareMixin 類為默認繼承類,在Django 1.10 之後需要該類的繼承,1.7-1.8 無需該類繼承
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
class M1(MiddlewareMixin):
# process_request 用於請求時過濾 判斷有沒有 USER_SESSION_KEY
def process_request(self, request, *args, **kwargs):
# path_info 獲取當前URL 的路徑值,不帶參數的路徑
# 如果Url 為 login 就返回一個None 讓請求繼續
if request.path_info == "/login/":
return None
else:
user_info = request.session.get(settings.USER_SESSION_KEY)
if not user_info:
return redirect("/login/")
# 如果頁面出現錯誤,將請求返回給/index/頁面(可以將錯誤信息記錄日誌)
def process_exception(self,request,exception):
print("=========",exception)
return redirect("/index/")
# 用於相應時過濾 必須有返回值
def process_response(self, request, response):
print("m1.process_response")
return response
2.在settings.py中引用該中間件
# 中間件配置
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"middlwares.md.M1", # 指定自定義中間件 位置
]
# SESSION 的別名
USER_SESSION_KEY = "user_info_key"
3.在views.py 中設置值
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
from app01.forms import LoginForm
from app01 import models
from django.conf import settings # 用戶自定義 + 內置的 settings 配置文件
from utils.md5 import md5 # utils 為自定義工具 包
def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, "login.html", {"form": form})
else:
# 將接收到的數據,傳給LoginForm()類 通過form 驗證;
form = LoginForm(request.POST)
# 通過 form 驗證後,form 為True
if form.is_valid():
# 通過form驗證的數據 存放在 cleaned_data 中
# form.cleaned_data
form.cleaned_data["password"] = md5(form.cleaned_data["password"])
# 通過 **form.cleaned_data 可以將 數據依照字典形式獲取 filter({"username":zhangsan,"password":1234})
userinfo = models.UserInfo.objects.filter(**form.cleaned_data).first() # 拿取第一個對象值
# 如果userinfo 中有數據,即表示驗證成功
if userinfo:
# 將 用戶信息 放置到 session 中
request.session[settings.USER_SESSION_KEY] = {"id": userinfo.pk, "username": userinfo.username}
# 重定向 頁面
return redirect("/index/")
else:
# 用戶驗證失敗,password 錯誤信息顯示在哪個 字段上
form.add_error("password", "用戶名或密碼錯誤")
# 存放錯誤信息 form.errors
# 將 form 清洗過的 數據直接返回給 html 模板
return render(request, "login.html", {"form": form})
def index(request):
return HttpResponse("驗證成功!")
# return render(request, "index.html")
4.定義工具模塊md5.py
import hashlib
def md5(text):
m = hashlib.md5()
m.update(text.encode("utf-8"))
return m.hexdigest()
if __name__ == '__main__':
text = "zhangsan"
print(md5(text))
5.forms.py 驗證配置
from django.forms import Form
# widgets 表示插件
from django.forms import widgets
# fields 表示所有的字段
from django.forms import fields
class LoginForm(Form):
username = fields.CharField(
label="用戶名",
required=True, # 表示不能為空,默認不可為空
error_messages={ # 錯誤信息 依照中文形式顯示
"required": "用戶名不能為空", # required 為真是錯誤信息
},
# 插件類型TextInput(attrs={"class": "自定義屬性 多個依照空格分隔 form-control 為bootcss屬性"})
widget=widgets.TextInput(attrs={"class": "form-control xxx aaa"})
)
password = fields.CharField(
label="密碼",
required=True, # 表示不能為空,默認不可為空
error_messages={ # 錯誤信息 依照中文形式顯示
"required": "密碼不能為空", # required 為真是錯誤信息
},
widget=widgets.PasswordInput(attrs={"class": "form-control"})
)
Django中間件 及 form 實現用戶登陸