• 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
     
     
     
  • 相关阅读:
    hdoj 1305字典树水题之二
    nyoj 547 水池加水 priority_queue优先级队列初体验
    nyoj167 找奶牛病毒 “按位或”运算 递归
    HDOJ4525 吃鸡腿 腾讯马拉松(五)
    hdoj 4523 切蛋糕 腾讯马拉松 大数加法比较
    如何学好3D游戏引擎编程《转自3D游戏引擎网》
    priority_queue 优先级队列的基本应用和重载问题
    poj1611 传染病 并查集
    srand((unsigned)time(NULL))和rand()
    最近被一个windows mobile照相的问题给难住了
  • 原文地址:https://www.cnblogs.com/ArmoredTitan/p/8751679.html
Copyright © 2020-2023  润新知