Django中間件部分
一、什麽是WSGI?
WEB框架的本質是一個socket服務端接收用戶請求,加工數據返回給客戶端(Django),但是Django沒有自帶socket需要使用 別人的 socket配合Django才能正常運行,socket有很多如下, 但是它們必須遵循一個規範 WSGI(web服務網關接口)這個所有socket都遵守的規範就是WSGI。
Django默認使用: wsgiref socket(並發性能低 測試使用)
在公司生產系統上一般用uwsgi+nginx+Django結合使用
wsgiref +Django工作流程
1.socket 接受客戶端請求 做http請求解析(分割請求頭請求體)
2.wsgiref 把解析之後請求相關信息轉發 給 Django
3.Django框架開始從:中間件-->路由系統(url)-->視圖函數(views)、ORM操作(操作數據庫,增刪改查)、模板渲染(前端輸入數據)最終return字符串給socket
4.socket send (Django產出的字符串),返回客戶端
Wsgi+Django from wsgiref.simple_server import make_server def RunServer(environ, start_response): Django框架開始 中間件 路由系統 視圖函數 。。。。。 start_response(View Code‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) return [bytes(‘<h1>Hello, web!</h1>‘, encoding=‘utf-8‘), ] if __name__ == ‘__main__‘: httpd = make_server(‘127.0.0.1‘, 8000, RunServer) httpd.serve_forever()
二、MVC/MTV是什麽?
是不有人經常在你面前 裝B的提起 MVC 和MTV?
說白了就是做功能模塊的劃分,把不同的代碼放到不同的文件。
MVC
models(數據庫,模型)
views(html模板)
controllers(業務邏輯處理,函數) --> MVC
MTV
models(數據庫,模型)
templates(html模板)
views(業務邏輯處理函數) --> MTV (Django屬於 MTV)
中間件:
http請求周期:
用戶在瀏覽器輸入url,在路由系統進行匹配,然後找到視圖函數,
然後取數據,拿模板渲染,把字符串返回給用戶
url----->中間件(管道)---->路由系統(url匹配)-->找到視圖函數,取數據,拿模板渲染,給用戶返回一個大的字符串
url------>中間件(class->class->class->class...)----->/login---------->def login(request)
中間件是由幾個類組成,經過類的方法
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‘,
]
用戶發請求,發給中間件middleware.security.SecurityMiddleware的方法1,再依次經過各個中間件的方法1, 再發到視圖函數,視圖函數的返回值(return HttpResponse() render(),redirect() ) 把返回值按照各個中間件的方法2返回給用戶 csrf:{% csrf_token %} 黑名單(ip1,ip2,ip3,ip4,ip5,ip6......) def process_request(self, request) def process_response(self, request, response) 請求這裏不能有return返回值,響應這裏必須有返回值 from django.utils.deprecation import MiddlewareMixin class Midlle1(MiddlewareMixin): def process_request(self, request): print(‘m1.process_request‘) # return request 可以不寫,Django會自動傳遞 如果請求寫返回值,不會繼續往下走,會提前結束 def process_response(self, request, response): print(‘m1.process_response‘) return response class Midlle1(MiddlewareMixin): def process_request(self, request): print(‘m1.process_request‘) # return request 可以不寫,Django會自動傳遞 # return HttpResponse(‘不要再往下走了‘) def process_response(self, request, response): print(‘m1.process_response‘) return response class Midlle2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘) # return request 可以不寫,Django會自動傳遞 # return HttpResponse(‘不要再往下走了‘) def process_response(self, request, response): print(‘m2.process_response‘) return response自定義中間件
Django 1.10版本之後,遇到return就返回,如果到了公司,有時候會遇到Django1.7或者1.8,遇到return 會找到最後的中間件的response,才返回
from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self,request): print(‘m1.process_request‘) def process_view(self, request, callback, callback_args, callback_kwargs): print(‘m1.process_view‘) def process_response(self,request,response): print(‘m1.process_response‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘) def process_view(self, request, callback, callback_args, callback_kwargs): print(‘m2.process_view‘) def process_response(self, request, response): print(‘m2.process_response‘) return response ‘‘‘ m1.process_request m2.process_request m1.process_view m2.process_view test m2.process_response m1.process_response ‘‘‘md.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^test/‘, views.test), url(r‘^login/‘, views.login), ]urls.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‘, ‘md.M1‘, ‘md.M2‘, ]中間件註冊
終極版:
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse,redirect,render class M1(MiddlewareMixin): def process_request(self,request): print(‘m1.process_request‘) def process_view(self, request, callback, callback_args, callback_kwargs): # print(callback, callback_args, callback_kwargs)#路由匹配<function test at 0x000000BC53849A60> () {} print(‘m1.process_view‘) # response = callback(request,*callback_args,**callback_kwargs) # return response def process_response(self,request,response): print(‘m1.process_response‘) return response def process_exception(self,request,exception): print(‘m1.process_exception‘) def process_template_response(self,request,response): print(‘m1.process_template_response‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘) #view_func視圖函數:callback def process_view(self, request, callback, callback_args, callback_kwargs): # print(callback,callback_args,callback_kwargs)#<function test at 0x0000001B0F2E9A60> () {} print(‘m2.process_view‘) # response = callback(request,*callback_args,**callback_kwargs) # return response def process_response(self, request, response): print(‘m2.process_response‘) return response def process_exception(self,request,exception): print(‘m2.process_exception‘) return HttpResponse(‘錯誤了......‘) def process_template_response(self,request,response): print(‘m2.process_template_response‘) return response """ 視圖函數的返回值中,如果有render方法,才會被調用執行 """ ‘‘‘ m1.process_request m2.process_request m1.process_view test m2.process_response m1.process_response ‘‘‘ ‘‘‘ m1.process_request m2.process_request m1.process_view m2.process_view test m2.process_response m1.process_response ‘‘‘ #五種中間件:最常用的是:process_request和process_response # process_request(self,request) # process_view(self, request, callback, callback_args, callback_kwargs) # process_template_response(self,request,response) # process_exception(self, request, exception) # process_response(self, request, response)md.py
class Foo: def __init__(self,req,status,msg): self.req = req self.status = status self.msg = msg def render(self): ret = { ‘status‘:self.status, ‘msg‘:self.msg } return HttpResponse(json.dumps(ret))#返回一個字符串 def test(request): # obj = Foo(request) return Foo(request,True,"錯誤信息") # print(‘test‘) # # int(‘asdf‘) # return HttpResponse(‘ok‘) """ 視圖函數的返回值中,如果有render方法,才會被調用執行 """ ‘‘‘ m1.process_request m2.process_request m1.process_view m2.process_view test m2.process_exception m1.process_exception m2.process_response m1.process_response ‘‘‘views.py
m1.process_request m2.process_request <function test at 0x000000BC53849A60> () {} m1.process_view <function test at 0x000000BC53849A60> () {} m2.process_view test m2.process_response m1.process_response process_request有返回值和 process_view有返回值的情況不一樣 process_request有返回值時,找到自己的response,自動返回, process_view有返回值時,會把所有的中間件的response都執行一遍再返回
process_exception 遇到views.py中出現異常時輸出,程序正確時不會打印m1.process_exception
ajax請求提交時,返回一個ret,還有一個json.dumps
中間件使用
緩存(memcache,redis) 去內存拿數據比硬盤快,請求來時,
先在緩存取,返回給用戶,HTTP請求發來時,要對所有請求做一下判斷,才用到中間件
- 應用:對所有請求或一部分請求做批量處理
Form表單初識
Form驗證:
就是對客戶端在form表單中輸入的數據,進行正確性驗證,驗證通過再做ORM操作,驗證失敗拋出提示信息。
基本使用
from django.shortcuts import render,redirect,HttpResponse from app01 import models from django.forms import Form from django.forms import fields import json # Create your views here. class JSONResponse: def __init__(self,req,status,msg): self.req = req self.status = status self.msg = msg def render(self): ret = { ‘status‘:self.status, ‘msg‘:self.msg } return HttpResponse(json.dumps(ret))#返回一個字符串 def test(request): # obj = Foo(request) return JSONResponse(request,True,"錯誤信息") #{"status": true, "msg": "\u9519\u8bef\u4fe1\u606f"} # print(‘test‘) # # int(‘asdf‘) # return HttpResponse(‘ok‘) class LoginForm(Form): # username = fields.CharField(max_lengtj=18,min_length=16, required=True) #正則驗證:不能為空,6-18位 username = fields.CharField( max_length=18, min_length=6, required=True,#不能為空 error_messages={ ‘required‘:‘用戶名不能為空‘, ‘min_length‘:‘太短了‘, ‘max_length‘:‘太長了‘, } ) #正則驗證:不能為空,16+ password = fields.CharField(min_length=16,required=True) error_messages = { ‘required‘: ‘密碼不能為空‘, ‘min_length‘: ‘太短了‘, ‘max_length‘: ‘太長了‘, } # email = fields.EmailField() 郵箱 # email = fields.GenericIPAddressField() IP # email = fields.IntegerField() #數字類型定義JSONResponse類
def login(request): if request.method == "GET": return render(request,‘login.html‘) else: obj = LoginForm(request.POST) ret = obj.is_valid() print(ret)#True or False if obj.is_valid(): #用戶輸入的格式正確 print(obj.cleaned_data)#字典類型#{‘username‘: ‘rootroot‘, ‘password‘: ‘rootrootrootrootroot‘} return redirect(‘http://www.baidu.com‘) else: #用戶輸入格式錯誤 print(obj.errors)#輸出一個對象, <ul class="errorlist"><li>username<ul class="errorlist"><li>用戶名太短了</li></ul></li><li>password<ul class="errorlist"><li>Ensure this value has at least 16 characters (it has 3).</li></ul></li></ul> # print(obj.errors[‘username‘][0]) # print(obj.errors[‘password‘][0]) return render(request,‘login.html‘,{‘obj‘:obj})定義login函數
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="POST" action="/login/"> {% csrf_token %} <div> <p> 用戶名:<input type="text" name="username">{{ obj.errors.username.0 }} </p> <p> 密 碼:<input type="password" name="password">{{ obj.errors.password.0 }} </p> <input type="submit" value="提交"> {{ msg }} </div> </form> </body> </html>login.html
#valid:有效的; 有法律效力的; 正當的; 健全的; user = request.POST.get(‘username‘) #不能為空,長度5-18位,必須郵箱格式 if len(user) < 6: pass pwd = request.POST.get(‘password‘) #不能為空,長度5-18位,包含數字,字母,下劃線 if user == ‘root‘ and pwd == ‘123‘: return redirect(‘http://www.baidu.com‘) else: return render(request,‘login.html‘,{‘msg‘:‘用戶名或密碼錯誤‘})雜項
用戶名密碼的驗證(比如用戶名是郵箱格式)
1.用戶提交的格式驗證,可以減輕數據庫的壓力
2.當輸入值的時候,輸入非法的字符
request.POST.get(‘username‘)
request.POST.get(‘password‘)
註冊頁面,登錄頁面(郵箱要用正則表達式驗證)
ip,port
- 需要對請求數據做驗證
- 獲取到數據然後進行驗證
郵箱正則(規則寫一遍,不需要重復)
- login:
郵箱正則
- register:
郵箱正則
問題:
- 重復進行用戶數據校驗:正則,長度,是否為空
- 無法記住上次提交內容,刷新頁面數據消失
Django提供 Form組件:
1. 定義規則
from django.forms import Form
from django.forms import fields
class xxx(Form):
xx = fields.CharField(required=True,max_lenght.,min,error_messages=)
fields:有一大堆的正則表達式,
CharField:用戶輸入的數據必須是字符串
required=True:不能為空
error_messages:定義錯誤信息的中文顯示
required=True,max_lenght.,min,error_messages:四個參數
2. 使用
obj = xxx(request.POST)
1).# 是否校驗成功
v = obj.is_valid()#怎麽匹配
# html標簽name屬性 = Form類字段名
2).# 所有錯誤信息
obj.errors
3).# 正確信息
obj.cleaned_data
request.POST要傳一個key,也就是前端傳的name屬性
html中的username和password和views.py中的username一一匹配
is_valid:在內部進行校驗
errors:所有的錯誤信息
cleaned_data:成功之後的正確信息(字典類型)
Django中間件部分