[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列表页