Django View Types
Basic information
- Django version: 2.1
Introduction
當一個 HTTP request被WSGI server接收時,在WSGIHandler中會根據url.py配置,找到對應的view function
相應代碼在WSGIHandler父類BaseHandler @django/core/handlers/base.py
wrapped_callback就是View function,上述可知,View function是一個接收三個參數的function
Django View Types
Django常用的view可以分為以下兩類
FBV(Function Based View)
- 優點
- 寫法容易,容易理解
- 可以直接使用Decorator
- 缺點
- 不便於繼承與重用
- 處理HTTP methods時,需要在內部使用條件判斷處理
示例
1234path("", index)def index(request):return HttpResponse("It is the index page")
- 優點
CBV(Class Based View)
- Django提供許多Built-in class-based views,分成以下兩類
- Base views
- 提供最基本的常用功能,可以直接使用或者繼承後使用
- Generic views的父類
- Generic views
- 提供常用的功能,例如數據展現或修改頁面
- 常用功能與對應Generic views如下:
- Display views
- ListView: 展現數據列表
- DetailView: 展現特定數據的詳細資料
- Edit views
- FormView: 用戶填寫Form後轉跳到對應頁面
- CreateView: 透過Form創建某項數據
- UpdateView: 更改數據資料
- DeleteView: 刪除數據
- Generic date views
- ArchiveIndexView: 從最近日期開始顯示數據列表
- YearArchiveView: 根據年過濾顯示數據列表
- MonthArchiveView: 根據年/月過濾顯示數據列表
- WeekArchiveView: 根據年/週過濾顯示數據列表
- DayArchiveView: 根據年/月/日過濾顯示數據列表
- TodayArchiveView: 根據今日過濾顯示數據列表
- DateDetailView: 顯示特定日期數據的詳細資料
- Display views
- Base views
- 可以搭配Class-based views mixins使用
- 上述提到View function只能是一個接收三個參數的function,Django在所有View的父類View @django/views/generic/base.py 提供一個as_view方法,可將CBV轉換成View function
當WSGIHandler的調用View function時,as_view內部會呼叫自身的dispatch,dispatch會根據http method調用View所實作對應名稱的function
1234567891011121314151617181920212223242526272829class View:def as_view(cls, **initkwargs):# ...def view(request, *args, **kwargs):print("[View] cls to init object")self = cls(**initkwargs)if hasattr(self, 'get') and not hasattr(self, 'head'):self.head = self.getself.setup(request, *args, **kwargs)if not hasattr(self, 'request'):raise AttributeError("%s instance has no 'request' attribute. Did you override ""setup() and forget to call super()?" % cls.__name__)return self.dispatch(request, *args, **kwargs)# ...return viewdef dispatch(self, request, *args, **kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else:handler = self.http_method_not_allowedreturn handler(request, *args, **kwargs)示例
12345path("", IndexView.as_view())class IndexView(View):def get(self, request, *args, **kwarg):return HttpResponese("It is the index page")
- Django提供許多Built-in class-based views,分成以下兩類