python測試開發django-73.django視圖 CBV 和 FBV


前言

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM