[Django 30Days] Day7 Blog實作範例一(Function-Based View&Class-Based View)

Day7 讓我們來看看View的兩種做法。

source: 鬼滅之刃

Django最重要的程式邏輯會集合在views.py,在這設計類別或函數將資料抓取後傳給Server或是先交給Template的渲染器後再傳到Server,其中View有兩種方法可以使用。

Function-Based View & Class-Based View入門

Django中有兩種方法可以實現View,一般初學者會先從FBV開始,而寫久的人會發現常常做這幾件事:

  1. 接收request後寫邏輯。
  2. 資料處理CRUD等。
  3. 回傳json(your context)。

因此CBV出現了,而CBV利用類別繼承重複使用程式碼,便於擴展,可以透過document看到有幾種類別的延伸可以依照需求使用。

Django’s View有三個必備要求:
1. 他們可以被調用的。一個view可以是FBV也可以是CBV。CBV繼承方法as_view(),它用了dispatch()方法來調用http動詞(get、post等)。
2. HttpRequest物件 必須在第一個參數位置。
3. 最後要回傳HttpResponse物件或是異常偵測。

Function-Based View & HTML

FBV優點:

  1. 容易實行
  2. 容易閱讀
  3. 明確地程式碼流程
  4. 裝飾器易於使用
  5. 適合一次性或特殊的功能

FBV缺點:

  1. 不好延伸、程式碼重複使用。
  2. 需透過條件判斷處理HTTP方法。

若要直接顯示資料到網頁上,最簡單的步驟,先到myblog/views.py編寫一個頁面相關的函數,接著建立myblog/urls.py並設定一個網址對應,最後proj底下也就是kimetsu/urls.py把myblog/urls.py使用include包進去。

以上由views.py設計的函數可以透過Http模組中的HttpResponse直接將要設定產生的網頁原始碼回傳。若往HttpResponse上層查看可以看到

HttpResponse(HttpResponseBase)函數的描述:
An HTTP response class with a string as content.
而HttpResponse則繼承HttpResponseBase。

views.py
第26行可以看到用了orm取文章的所有資料。
第27~33行設定好表格欄位名稱。
第35~40行透過for迴圈將blog_post物件迭代後依照欄位取出變數值。
第41行最後格式化字串塞入html變數裡面回傳。下圖為網頁結果。

前面說了,views是用來做運算邏輯的地方,因此將運算邏輯與html混在一起,當程式用來用大時是非常不好的,因此會在templates資料夾集中html並結合模板語言傳送到前端顯示給使用者。接下來來建立好我們的Templates吧!

改寫為Class-Based View

CBV優點:

  1. 程式碼重複使用: CBV中,一個view可以被另一個view繼承,並針對不同的使用內容做修改。
  2. DRY設計原則: 減少程式碼重複。
  3. 程式碼容易擴展: 其中有Mixins方法擴展CBV包含更多功能。
  4. 程式碼的結構: CBV可以用類別實體方法幫助你回傳不同的http request,而不是使用條件判斷。
  5. 可以建立於 generic class-based views上面。

CBV缺點:

  1. 程式碼不好閱讀。
  2. 程式碼流程較不易理解。
  3. 裝飾器需要額外導入或重寫。

首先在views.py中建立類別AboutView繼承View並使用get方法,接著在urls.py中import AboutView,as_view()是一個request與reponse過程的主要進入點,它會接收request並回傳對應的response。

根據Django官方的建議:

If you find you’re struggling to implement your view as a subclass of a generic view, then you may find it more effective to write just the code you need, using your own class-based or functional views.

要用FBV還是CBV並沒有一個答案,一般人習慣哪個就用哪個或者是更進階一點依照需求去選擇使用,兩者並不能互相取代。

Vitor Fieitas文章有提到一些例子。
FBV ex:適合處理多表單。
CBV 功能集中在某個CBV中,ex:ListView 使用在文章列表頁。

Reference:

Django documentation
https://docs.djangoproject.com/en/3.1/ref/class-based-views/base/#django.views.generic.base.View.as_view

何敏煌 — Python新手使用django架站技術實作

Vitor Fieitas — Class-Based Views vs. Function-Based Views

--

--