[TOC]
使用函數方式定義的視圖叫函數視圖,雖然使用方便,便于理解,但是當一個s視圖有多種請求方式的時候,變需要使用分支來編寫不同請求方式對應的邏輯。
使用函數視圖,代碼看上去是這樣子的
```python
def my_view(request):
if request.method == 'GET':
return HttpResponse("get")
if request.method == 'POST':
return HttpResponse("post")
```
## 1. 使用類視圖
基于類的視圖的核心是允許你用不同的實例方法來響應不同的HTTP請求方法,而不是在一個視圖函數中使用條件分支代碼來實現。
### 創建類視圖
使用類視圖,代碼是這樣子的
```python
from django.views import View
class ClassView(View):
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
類視圖需要繼承django提供的 `View` 類,使用 `from django.views import View` 導入
### 注冊路由
配置類視圖的時候,使用類視圖的 `as_view` 方法注冊路由
```python
urlpatterns = [
url(r'^class_view', views.ClassView.as_view(), name="class_view")
]
```
`as_view` 會返回類中一個函數的引用,它會到 `View` 中,執行 `dispatch` 方法, `dispatch` 會方法會在類中查找類似GET\POST之類的類方法,然后和請求方式進行匹配,匹配上了,就返回該函數的引用。
如果向上邊的類視圖發送一個 `GET` 請求,他會把 `GET` 轉換為小寫形式并和類中的方法進行匹配,然后匹配到 `get` 方法,會把 `get` 方法的引用返回到 `as_view` 調用處。所以在 `get` 請求下最后 `as_view` 是 `get` 函數的引用。
## 類視圖使用裝飾器
可以使用裝飾器為類視圖增加功能,使用裝飾器有三種方式。
- 在url配置中裝飾
- 在類視圖中裝飾
- 使用Mixin擴展類
為了便于理解,使用下邊的案例做演示
```python
def decorator(func):
def wrapper(request, *args, **kwargs):
print('裝飾器被調用')
return func(request, *args, **kwargs)
return wrapper
class ClassView(View):
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
### 在url中裝飾
```
url(r'^class_view', views.decorator(views.ClassView.as_view()), name="class_view")
```
發送 `GET` 或者 `POST` 類型請求打印結果
```
裝飾器被調用
```
在url中調用該函數,并把 `as_view` 函數傳入即可,這種方式會把所有被請求的函數都進行裝飾。
這種方法把裝飾放到了url配置中,不利于代碼的完整性和可讀性,所以一般情況下不使用。
### 在類視圖中裝飾
在類視圖中使用裝飾器不能直接裝飾,需要使用 `method_decorator` 把裝飾器轉換位適用于類的裝飾器。
在我們寫的裝飾器中,內層函數接收的參數為 `request`
```python
def decorator(func):
def wrapper(request, *args, **kwargs):
print('裝飾器被調用')
return func(request, *args, **kwargs)
return wrapper
```
而在類視圖的函數中,第一個參數是 `self` ,所以要使用 `method_decorator` 把裝飾器的第一個參數補充為 `self` 以使用類視圖中的函數。
也可以手動為裝飾器添加參數 `self`
```python
def decorator(func):
def wrapper(self, request, *args, **kwargs):
print('裝飾器被調用')
return func(self, request, *args, **kwargs)
return wrapper
```
#### 裝飾所有函數
可以重寫并裝飾類的 `dispatch` 函數,代碼如下
```python
class ClassView(View):
@method_decorator(decorator)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
使用 `GET` 或者 `POST` 方式請求,都會執行裝飾器,打印結果
```
裝飾器被調用
```
#### 只裝飾某一個函數
```python
class ClassView(View):
@method_decorator(decorator)
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
只有使用 `GET` 方式請求,才會執行裝飾器,打印結果
```
裝飾器被調用
```
`POST` 方式不會執行裝飾器。
### method_decorator 的 name 參數
裝飾全部函數
```python
@method_decorator(decorator, name="dispatch")
class ClassView(View):
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
指定被裝飾的函數
```python
@method_decorator(decorator, name="get")
class ClassView(View):
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
## 使用Mixin擴展類
擴展類使用了 Python 多繼承的 `MRO` 特性。
```
class MyMixin(object):
@classmethod
def as_view(cls, *args, **kwargs):
view = super().as_view(*args, **kwargs)
view = decorator(view)
return view
class ClassView(MyMixin, View):
def get(self, request):
return HttpResponse("get")
def post(self, request):
return HttpResponse("post")
```
這種方式會裝飾所有函數,可以使用這種方式為函數添加多個裝飾器。
- 1.介紹
- 2.工程搭建
- 2.1.環境配置
- 2.2.創建工程
- 2.3.創建子應用
- 2.3.1.pycharm打開項目
- 2.4.創建視圖
- 3.基本配置
- 3.1.settings基本配置項
- 3.2.路由配置
- 4.請求響應
- 4.1.request
- 4.2.response
- 4.3.cookie
- 4.4.session
- 5.類視圖中間件
- 5.1.類視圖
- 5.2中間件
- 6.數據庫
- 6.1.數據庫配置
- 6.2定義模型類
- 6.3數據庫遷移
- 6.4數據庫操作
- 6.5查詢集
- 6.6模型管理器
- 7.模板表單
- 7.1使用模板
- 7.2模板標簽
- 7.3表單
- 8.后臺管理
- 8.1Admin
- 8.2自定義模型類樣式
- 8.3列表頁