當我們在 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
| 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
|
from datetime import date from django.template.response import TemplateResponse
def example_view(request, arg, **kwargs): kwargs['today'] = date.today() return TemplateResponse(request, 'blog/example.html', { 'arg': arg, **kwargs })
|
1 2 3 4
|
example page {{ arg }} today is {{ today }}
|
這時,如果你在網址中輸入參數 arg
,頁面就會顯示相應的內容,例如:
當然,我們也可以用 HttpResponse 等效完成這樣的功能:
- 最簡單的 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"] }')
|
- 使用 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))
|
- 使用 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
| 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
| 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,例如 TemplateView
、ListView
、DetailView
等,詳細內容可以見文章一開始的表格,這些內建的視圖可以幫助我們快速完成常見功能,省去不少麻煩,今天先分享到這裡,後續會帶大家深入介紹更多的 CBV 內建視圖,敬請期待~
本篇文章是我由以下參考資料整理+自己繪圖而成,如果您有興趣了解更多,請參考:
參考資料:
Django Views — The Right Way
Django Docs - CBV
Comments