[Django 30Days] Day7 Blog實作範例一(Function-Based View&Class-Based View)
Day7 讓我們來看看View的兩種做法。
Django最重要的程式邏輯會集合在views.py,在這設計類別或函數將資料抓取後傳給Server或是先交給Template的渲染器後再傳到Server,其中View有兩種方法可以使用。
Function-Based View & Class-Based View入門
Django中有兩種方法可以實現View,一般初學者會先從FBV開始,而寫久的人會發現常常做這幾件事:
- 接收request後寫邏輯。
- 資料處理CRUD等。
- 回傳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優點:
- 容易實行
- 容易閱讀
- 明確地程式碼流程
- 裝飾器易於使用
- 適合一次性或特殊的功能
FBV缺點:
- 不好延伸、程式碼重複使用。
- 需透過條件判斷處理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優點:
- 程式碼重複使用: CBV中,一個view可以被另一個view繼承,並針對不同的使用內容做修改。
- DRY設計原則: 減少程式碼重複。
- 程式碼容易擴展: 其中有Mixins方法擴展CBV包含更多功能。
- 程式碼的結構: CBV可以用類別實體方法幫助你回傳不同的http request,而不是使用條件判斷。
- 可以建立於 generic class-based views上面。
CBV缺點:
- 程式碼不好閱讀。
- 程式碼流程較不易理解。
- 裝飾器需要額外導入或重寫。
首先在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