FBV(function based views),即基於函數的視圖。FBV 簡單易懂,但是難以復用。它們不能像 CBV 那樣能從父類中繼承。FBV 的編寫指南要求我們:視圖代碼越少越好;視圖代碼不能重復;視圖應該只處理呈現邏輯。業務邏輯應盡可能放在數據模型中,或者表單對象中;視圖代碼要保持簡單;使用它們來編寫自定義的 403, 404, 500 等錯誤處理器;避免使用嵌套的 if 塊。CBV是View類的集成類;這裡的主要區別在於請求是以HTTP方法命名的類方法內處理的,例如GET ,POST ,PUT ,HEAD等。所以,在這裡,我們不需要做一個條件來判斷請求是一個 POST 還是它是一個 GET 。代碼會直接跳轉到正確的方法中,在 View 類中內部處理了這個邏輯。
from django.shortcuts import render, redirect
def login(request):
if request.method == "GET":
"""
處理GET請求
"""
return render(request, 'login.html')
if request.method == "GET":
"""
處理POST請求
"""
user = request.POST.get('username')
pwd = request.POST.get('password')
if username == 'tony' and password == "123456":
request.session['user'] = user
return redirect('/index/')
return render(request, 'login.html')
# urls.py中
url(r'^login/$', views.login),
CBV是基於類的視圖,就是使用了類來處理用戶的請求,不同的請求我們可以在類中使用不同方法來處理,這樣大大的提高了代碼的可讀性。CBV允許我們使用不同的實例方法來響應不同的HTTP請求方法,而不是像FBV那樣使用條件分支代碼。但是定義的類要繼承父類View,所以我們在使用CBV的時候需要提前引入庫:from django.views import View
執行對應請求的方法前會優先執行 dispatch 方法(在get/post/put…方法前執行),dispatch() 方法會根據請求的不同調用相應的方法來處理。其實,在我們前面學到的知識都知道 Django 的 url 是將一個請求分配給可調用的函數的,而不是一個類,那是如何實現基於類的視圖的呢? 主要還是通過父類 View 提供的一個靜態方法 as_view() ,as_view 方法是基於類的外部接口, 他返回一個視圖函數,調用後請求會傳遞給 dispatch 方法,dispatch 方法再根據不同請求來處理不同的方法。
from django.shortcuts import render,HttpResponse
from django.views import View
class LoginView(View):
def get(self, request):
"""
處理GET請求
"""
return render(request, 'login.html')
def post(self, request):
"""
處理POST請求
"""
user = request.POST.get('username')
pwd = request.POST.get('password')
if username == 'tony' and password == "123456":
request.session['user'] = user
return redirect('/index/')
return render(request, 'login.html')
# urls.py中
url(r'^user/$', views.LoginView.as_view()),
CBV 將整個視圖函數的邏輯拆成了類下的多個函數,依靠函數調用來實現完整的邏輯;提高代碼的可復用性,更加靈活,讓開發者使用面向對象的技術,比如多繼承、多態等;可以用不同的函數針對不同的 HTTP 方法處理,而不是通過很多 if 判斷,提高代碼可讀性。
當我們使用CBV方式時,首先要注意urls.py文件中要寫成“類名.as_view()”方式映射,其次在類中我們定義的get/post方法這些方法的名字不是我們自己定義的,而是按照固定樣式,View類中支持以下方法:
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']