zoukankan      html  css  js  c++  java
  • 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")
    
    

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

  • 相关阅读:
    微软官方Windows Phone初学者开发视频系列从零开始带您轻松进入开发的世界
    Flash务实主义(五)——AS3的垃圾回收
    各种流行的编程风格
    程序设计的十个做与不做
    Android 上的 10 款 Web 开发工具推荐
    Flex 中的 DataGrid 自动刷新(转)
    Flex 序列化自定义类 解决 sharedObject 保存自定义对象
    Adobe更新手机应用开发工具 涵盖所有平台
    程序员的七大坏毛病
    怎样让失败变成成功之母?
  • 原文地址:https://www.cnblogs.com/mxuanli/p/9847869.html
Copyright © 2011-2022 走看看