前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >django的类视图-11

django的类视图-11

作者头像
py3study
发布2020-01-19 10:03:57
7330
发布2020-01-19 10:03:57
举报
文章被收录于专栏:python3python3

目录

使用函数方式定义的视图叫函数视图,虽然使用方便,便于理解,但是当一个s视图有多种请求方式的时候,变需要使用分支来编写不同请求方式对应的逻辑。

使用函数视图,代码看上去是这样子的

代码语言:javascript
复制
def my_view(request):
    if request.method == 'GET':
        return HttpResponse("get")
    if request.method == 'POST':
        return HttpResponse("post")

1. 使用类视图

基于类的视图的核心是允许你用不同的实例方法来响应不同的HTTP请求方法,而不是在一个视图函数中使用条件分支代码来实现。

创建类视图

使用类视图,代码是这样子的

代码语言:javascript
复制
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 方法注册路由

代码语言:javascript
复制
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_viewget 方法的引用。

类视图使用装饰器

可以使用装饰器为类视图增加功能,使用装饰器有三种方式。

  • 在url配置中装饰
  • 在类视图中装饰
  • 使用Mixin扩展类

为了便于理解,使用下边的案例做演示

代码语言:javascript
复制
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中装饰

代码语言:javascript
复制
url(r'^class_view', views.decorator(views.ClassView.as_view()), name="class_view")

发送 GET 或者 POST 类型请求打印结果

代码语言:javascript
复制
装饰器被调用

在url中调用该函数,并把 as_view 方法传入即可,这种方式会把所有被请求的函数都进行装饰。

这种方法把装饰放到了url配置中,不利于代码的完整性和可读性,所以一般情况下不使用。

在类视图中装饰

在类视图中使用装饰器不能直接装饰,需要使用 method_decorator 把装饰器转换位适用于类的装饰器。

在我们写的装饰器中,内层函数接收的参数为 request

代码语言:javascript
复制
def decorator(func):
    def wrapper(request, *args, **kwargs):
        print('装饰器被调用')
        return func(request, *args, **kwargs)
    return wrapper

而在类视图的方法中,第一个参数是 self ,所以要使用 method_decorator 把装饰器的第一个参数补充为 self 以使用类视图中的方法。

也可以手动为装饰器添加参数 self

代码语言:javascript
复制
def decorator(func):
    def wrapper(self, request, *args, **kwargs):
        print('装饰器被调用')
        return func(self, request, *args, **kwargs)
    return wrapper
装饰所有方法

可以重写并装饰类的 dispatch 方法,代码如下

代码语言:javascript
复制
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 方式请求,都会执行装饰器,打印结果

代码语言:javascript
复制
装饰器被调用
只装饰某一个方法
代码语言:javascript
复制
class ClassView(View):

    @method_decorator(decorator)
    def get(self, request):
        return HttpResponse("get")

    def post(self, request):
        return HttpResponse("post")

只有使用 GET 方式请求,才会执行装饰器,打印结果

代码语言:javascript
复制
装饰器被调用

POST 方式不会执行装饰器。

method_decorator 的 name 参数

装饰全部方法

代码语言:javascript
复制
@method_decorator(decorator, name="dispatch")
class ClassView(View):

    def get(self, request):
        return HttpResponse("get")

    def post(self, request):
        return HttpResponse("post")

指定被装饰的方法

代码语言:javascript
复制
@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 特性。

代码语言:javascript
复制
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")

这种方式会装饰所有方法,可以使用这种方式为方法添加多个装饰器。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 使用类视图
    • 创建类视图
      • 注册路由
      • 类视图使用装饰器
        • 在url中装饰
          • 在类视图中装饰
            • 装饰所有方法
            • 只装饰某一个方法
          • method_decorator 的 name 参数
          • 使用Mixin扩展类
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档