(django)11类视图

Posted mxuanli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(django)11类视图相关的知识,希望对你有一定的参考价值。

目录

使用函数方式定义的视图叫函数视图,虽然使用方便,便于理解,但是当一个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 会方法会在类中查找类似GETPOST之类的类方法,然后和请求方式进行匹配,匹配上了,就返回该方法的引用。

如果向上边的类视图发送一个 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")

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

以上是关于(django)11类视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在Django视图中使用for循环返回每次迭代[关闭]

如何在片段类的列表视图中显示 SQLite 数据库?

如何从片段内的列表视图打开链接网址?

使用 json rereiver php mysql 在片段中填充列表视图

如何在 Django 通用列表视图类中使用 slugfield 创建链接?

Django视图系统 -- 2019-08-11 19:36:29