前言
FBV(function base views) 就是在視圖里使用函數處理請求,這一般是學django入門的時候開始使用的方式。
CBV(class base views) 就是在視圖里使用類處理請求,這是面向對象的編程方式。
面試的時候基本上都是問到:你平常寫的視圖是基於函數的視圖 (FBV),還是基於類的視圖 (CBV),兩者的區別在哪?
如果你只會寫基於函數的視圖,那說明還處於初級入門的階段了。
FBV 模式
FBV(function base views)在views.py文件中定義視圖函數來處理用戶請求,函數中通過 if 判斷 request.method 請求方式是 GET 還是 POST請求做對應的處理。
# views.py
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
# 上海-悠悠,QQ交流群:750815713
# Create your views here.
# function base views
def fbvdemo(request):
'''function base views'''
context = {
"code": 0,
"msg": ""
}
if request.method == "GET":
context["msg"] = "這是fbvdemo get請求"
return JsonResponse(context)
if request.method == "POST":
context["msg"] = "這是fbvdemo POST請求"
return JsonResponse(context)
urls.py配置訪問路徑
from django.conf.urls import url
urlpatterns = [
url(r'^fbvdemo/$', views.fbvdemo)
]
CBV 模式
CBV(class base views) 就是在視圖里使用類處理請求
- 自定義的類必須繼承 View 父類
- 提高了代碼的復用性,可以使用面向對象的技術,比如 Mixin(多繼承)
- 可以用不同的函數針對不同的 HTTP 方法處理,而不是通過很多if判斷,提高代碼可讀性
- CBV 模式繼承的View類提供了多種請求方式對應的響應函數不需要在進行判斷,可以直接在子類重寫繼承的方法
- CBV 模式子類繼承重寫父類請求方式的響應函數通過父類 dispatch 方法進行反射分發
- 在 urls.py 路由系統中必須使用 Myview.as_view() 替代視圖函數
# views.py
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
# Create your views here.
# 上海-悠悠,QQ交流群:750815713
# class base views
class Cbvdemo(View):
context = {
"code": 0,
"msg": ""
}
def get(self, request):
self.context["msg"] = "這是Cbvdemo get請求"
return JsonResponse(self.context)
def post(self, request):
self.context["msg"] = "這是Cbvdemo post請求"
return JsonResponse(self.context)
urls.py 配置訪問路徑
from django.conf.urls import url
urlpatterns = [
url(r'^fbvdemo/$', views.fbvdemo),
url(r'^cbvdemo/$', views.Cbvdemo.as_view()),
]
這2種方式從功能上講都可以實現對應的功能,從代碼的可讀性來講,建議多使用 CBV 模式。
另外通過 CBV 如果想要在執行get或post方法前執行其他步驟,可以重寫dispatch。
login_requierd登錄校驗
FBV 模式如果需要加登錄之后才能訪問,只需在函數上加裝飾器@login_required
from django.contrib.auth.decorators import login_required
# function base views
@login_required
def fbvdemo(request):
'''function base views'''
context = {
"code": 0,
"msg": ""
}
if request.method == "GET":
context["msg"] = "這是fbvdemo get請求"
return JsonResponse(context)
if request.method == "POST":
context["msg"] = "這是fbvdemo POST請求"
return JsonResponse(context)
沒加裝飾器之前,可以直接訪問
C:\Users\dell>http http://localhost:8000/fbvdemo/
HTTP/1.1 200 OK
Content-Length: 55
Content-Type: application/json
Date: Sat, 23 Nov 2019 06:26:58 GMT
Server: WSGIServer/0.2 CPython/3.6.0
Vary: Origin
X-Frame-Options: SAMEORIGIN
{
"code": 0,
"msg": "這是個get請求"
}
加了@login_required裝飾器后,沒登錄的話會302重定向到登錄頁 /accounts/login/
C:\Users\dell>http http://localhost:8000/fbvdemo/
HTTP/1.1 302 Found
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Sat, 23 Nov 2019 06:27:19 GMT
Location: /accounts/login/?next=/fbvdemo/
Server: WSGIServer/0.2 CPython/3.6.0
Vary: Origin, Cookie
X-Frame-Options: SAMEORIGIN
CBV 模式加 login_requierd 登錄校驗
method_decorator給CBV視圖添加登錄校驗。
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
# 上海-悠悠,QQ交流群:750815713
class Cbvdemo(View):
context = {
"code": 0,
"msg": ""
}
@method_decorator(login_required)
def get(self, request):
self.context["msg"] = "這是Cbvdemo get請求"
return JsonResponse(self.context)
@method_decorator(login_required)
def post(self, request):
self.context["msg"] = "這是Cbvdemo post請求"
return JsonResponse(self.context)
也可以直接在class上用裝飾器
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
@method_decorator(login_required, name='get')
@method_decorator(login_required, name='post')
class Cbvdemo(View):
context = {
"code": 0,
"msg": ""
}
def get(self, request):
self.context["msg"] = "這是Cbvdemo get請求"
return JsonResponse(self.context)
def post(self, request):
self.context["msg"] = "這是Cbvdemo post請求"
return JsonResponse(self.context)