欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

(django)11类视图

程序员文章站 2022-06-30 14:02:34
[TOC] 使用函数方式定义的视图叫函数视图,虽然使用方便,便于理解,但是当一个s视图有多种请求方式的时候,变需要使用分支来编写不同请求方式对应的逻辑。 使用函数视图,代码看上去是这样子的 1. 使用类视图 基于类的视图的核心是允许你用不同的实例方法来响应不同的HTTP请求方法,而不是在一个视图函数 ......

目录

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

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

def my_view(request):
    if request.method == 'get':
        return httpresponse("get")
    if request.method == 'post':
        return httpresponse("post")

1. 使用类视图

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

创建类视图

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

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 方法注册路由

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扩展类

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

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

def decorator(func):
    def wrapper(request, *args, **kwargs):
        print('装饰器被调用')
        return func(request, *args, **kwargs)
    return wrapper

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

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

def decorator(func):
    def wrapper(self, request, *args, **kwargs):
        print('装饰器被调用')
        return func(self, request, *args, **kwargs)
    return wrapper

装饰所有方法

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

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 方式请求,都会执行装饰器,打印结果

装饰器被调用

只装饰某一个方法

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 参数

装饰全部方法

@method_decorator(decorator, name="dispatch")
class classview(view):

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

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

指定被装饰的方法

@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")

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