zoukankan      html  css  js  c++  java
  • Django源码理解一

    Django视图CBV的dispatch相关源码解析
     
     
    一般cbv视图写法:
    class Foo(View):
        def get(request):
            return HttpResponse('GET')
    一般路由写法:
    urlpatterns = [
        # url(r‘^index/‘, views.index),
        url(r‘^index/‘, views.Index.as_view()),
    ]
     
    Django在通过路由as_view()方法,会执行基类View中的dispatch方法,在通过dispatch方法执行具体的方法视图。
     
    在这个方法中会先判断这个请求的method是否在http_metod_names列表中。
    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    这个列表是http协议中的请求方法,我们也可以通过修改源码,自定义请求类型。
     
    然后dispatch通过getattr,从self这个对象中找method方法(小写,因为我们试图类里都是小写的方法名),找到之后运行并传参。
        def dispatch(self, request, *args, **kwargs):
            # Try to dispatch to the right method; if a method doesn't exist,
            # defer to the error handler. Also defer to the error handler if the
            # request method isn't on the approved list.
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
     
    由上面这个源码原理我们具体分析dispatch运行过程如下:
     
    from django.views import View
    class StudentView(View):
        def dispatch(self,request,*args,**kwargs):
            ret =super(StudentView,self).dispatch(request,*args,**kwargs)
            return ret
        def get(self,request,*args,**kwargs):
            return HttpResponse('GET')
     
    总结:
    1 通过视图的as_view()运行源码as_view()
    as_view会return dispatch这个方法
    2 执行 Student类里自己的dispatch,因为我们重写了这个方法,所以先运行自己的。
    自己的这个dispatch通过super找到了源码的dispatch.
    3 源码的dispatch先判断请求的method是否在http_method_names
    然后通过反射getattr,找到method,这个method又回到了Student类里的具体的method方法。
    4 最后运行我们重写的dispatch中的return ret返回给用户。
     
    所以我们重写的这个dispatch的原理就有点像装饰器,如果我们在super之前写一个print('before'),return之前写一个print('after'),那么每次浏览器请求之前都会先打印before,返回给用户之前都会打印after。
    示例如下:
    from django.views import View
    class StudentView(View):
        def dispatch(self,request,*args,**kwargs):
            print('before')
            ret =super(StudentView,self).dispatch(request,*args,**kwargs)
            print('after')
            return ret
     
     
     
  • 相关阅读:
    Unreal Engine 4官网教程
    快速上手制作暗黑类游戏动作打击感的一些要点
    充分利用 UE4 中的噪声
    综合帖:多角度闲聊游戏打击感
    鹅厂内部分享:七步教你从无到有做数值
    二叉树、二叉搜索树、平衡二叉树、B树、B+树的精确定义和区别探究
    MySQL的InnoDB索引原理详解
    分布式核心
    Mysql 原理以及常见mysql 索引等
    redis核心原理
  • 原文地址:https://www.cnblogs.com/ArmoredTitan/p/8751679.html
Copyright © 2011-2022 走看看