Django視圖之FBV與CBV


一. CBV與FBV

  CBV:Class Based View

  FBV:Function Based View

  我們之前寫過的都是基於函數的view,就叫FBV。還可以把view寫成基於類的,那就是CBV。

  下面我們就以前面所寫的圖書管理系統中的添加出版社為例:

  FBV版本:

# 新增出版社
def add_publisher(request):
    if request.method == "POST":
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")
    return render(request, "add_publisher.html")

  CBV版本:

from django.views import View
 
 
class AddPublisher(View):
    def get(self, request):
        return render(request, "add_publisher.html")
 
    def post(self, request):
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")

  注意:使用CBV時,urls.py中也做對應的修改:

path('add_publisher/', views.AddPublisher.as_view()),  # 新增出版社  

二. 給視圖加裝飾器

  1. 使用裝飾器裝飾FBV

  FBV本身就是一個函數,所以和給普通的函數加裝飾器無差:

def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time - start_time)
        return ret
 
    return inner
 
 
# 新增出版社
@wrapper
def add_publisher(request):
    if request.method == "POST":
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")
    return render(request, "add_publisher.html")
  2. 使用裝飾器裝飾CBV

  類中的方法與獨立函數不完全相同,因此不能直接將函數裝飾器應用於類中的方法 ,我們需要先將其轉換為方法裝飾器。Django中提供了method_decorator裝飾器用於將函數裝飾器轉換為方法裝飾器。

  方式一:給某個方法加上裝飾器(此例給get方法加上)

from django.views import View
from django.utils.decorators import method_decorator
 
 
class AddPublisher(View):  # CBV版
    @method_decorator(wrapper)
    def get(self, request):
        return render(request, "add_publisher.html")
 
    def post(self, request):
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")

  方式二:加在dispatch方法上面,會給類下的所有方法加上此裝飾器

class AddPublisher(View):  # CBV版
    @method_decorator(wrapper)
    def dispatch(self, request, *args, **kwargs):
        obj = super(AddPublisher, self).dispatch(request, *args, **kwargs)
        return obj
 
    def get(self, request):
        return render(request, "add_publisher.html")
 
    def post(self, request):
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")

  方式三:加在類上面

@method_decorator(wrapper, name="post")
@method_decorator(wrapper, name="get")  # 給哪個方法加,就要指定name
class AddPublisher(View):  # CBV版
    def dispatch(self, request, *args, **kwargs):
        obj = super(AddPublisher, self).dispatch(request, *args, **kwargs)
        return obj
 
    def get(self, request):
        return render(request, "add_publisher.html")
 
    def post(self, request):
        pub_name = request.POST.get("name")
        models.Publisher.objects.create(name=pub_name)
        return redirect("/publisher_list/")

  

 


免責聲明!

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



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