Django: FBV & CBV - TemplateView

Django Django-CBV

當我們在 Django 中談到 View,它就像是網頁的「大腦」,負責處理邏輯、連接 HTML 和資料庫的 Model(類似於 MVC 架構中的 Controller,可以參考:Ruby on Rails: MVC 是什麼?)。在 Django 裡,我們有兩種主要的方式來撰寫 View:FBV(Function-Based Views)CBV(Class-Based Views)

FBV(Function-Based Views):使用 Python 函數來撰寫 View。這種方式比較簡單直接,是 Django 最原始的寫法。每個 FBV 會接收一個 HttpRequest,然後返回一個 HttpResponse

CBV(Class-Based Views):使用 Python 類來定義 View。這種方式讓你避免寫太多重複的程式,非常符合 DRY(Don’t Repeat Yourself)原則。

看文字說明可能有點抽象,讓我帶來幾個範例:
範例檔案可以參考GitHub

FBV

這裡用 TemplateResponse 來寫一個簡單的範例:

1
2
3
4
5
6
7
8
9
#url.py
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
path('example/<str:arg>/', views.example_view, name='example_name'),
]
1
2
3
4
5
6
7
8
9
#views.py

from datetime import date
from django.template.response import TemplateResponse

# *args:會給tuple格式的參數; **kwargs:提供dictionary格式的參數
def example_view(request, arg, **kwargs):
kwargs['today'] = date.today()
return TemplateResponse(request, 'blog/example.html', { 'arg': arg, **kwargs })
1
2
3
4
# blog/example.html

example page {{ arg }}
today is {{ today }}

這時,如果你在網址中輸入參數 arg,頁面就會顯示相應的內容,例如:

當然,我們也可以用 HttpResponse 等效完成這樣的功能:

  1. 最簡單的 HttpResponse
1
2
3
4
5
6
from datetime import date
from django.http import HttpResponse

def example_view(request, arg, **kwargs):
kwargs['today'] = date.today()
return HttpResponse(f'example page {arg}, today is { kwargs["today"] }')
  1. 使用 HttpResponse 和 loader
1
2
3
4
5
6
7
8
9
10
11
12
from datetime import date
from django.http import HttpResponse
from django.template import loader

def example_view(request, my_arg, **kwargs):
kwargs['today'] = date.today()
template = loader.get_template('blog/example.html')
context = {
'my_arg': my_arg,
**kwargs
}
return HttpResponse(template.render(context, request))
  1. 使用 render 函數
1
2
3
4
5
6
7
from datetime import date
from django.http import HttpResponse
from django.shortcuts import render

def example_view(request, arg, **kwargs):
kwargs['today'] = date.today()
return render(request, 'blog/example.html', {'arg': arg, **kwargs})

以上就是 FBV 的基礎介紹,接下來來介紹 CBV

CBV:

CBV 是 Django 內建提供的一種較新的寫法,通過類來完成視圖邏輯。它有很多優點,比如可以輕鬆重複使用程式,讓結構更清晰。

使用 CBV,我們可以將上面的範例改寫成這樣的 TempalteView:

1
2
3
4
5
6
7
8
9
# views.py
class HomeView(TemplateView):
template_name = "blog/index.html"

def get_context_data(self, arg, **kwargs):
context = super().get_context_data(**kwargs)
context['today'] = date.today()
context['arg'] = arg
return context
1
2
3
4
5
6
# urls.py
from django.urls import path
from . import views

urlpatterns = [
path('<str:arg>/', views.HomeView.as_view(), name='index'),

雖然乍看之下,CBV 和 FBV 寫起來好像差不多,但實際上,CBV 的重用性更強,代碼更加結構化。當開始寫更多的邏輯時,CBV 的優勢就會變得明顯,尤其是它的「固定寫法」,讓我們不必去糾結於到底該用哪種 HttpResponse。這對習慣了 Ruby on Rails 的「convention over configuration」的人來說,會更有親切感。

Django 提供了許多內建的 CBV,例如 TemplateViewListViewDetailView 等,詳細內容可以見文章一開始的表格,這些內建的視圖可以幫助我們快速完成常見功能,省去不少麻煩,今天先分享到這裡,後續會帶大家深入介紹更多的 CBV 內建視圖,敬請期待~

本篇文章是我由以下參考資料整理+自己繪圖而成,如果您有興趣了解更多,請參考:

參考資料:

Django Views — The Right Way

Django Docs - CBV

Comments