zoukankan      html  css  js  c++  java
  • django CBV视图源码分析

    典型FBV视图例子

    url路由系统

    from django.conf.urls import url
    from django.contrib import admin
    from luffycity.views import BookView, AuthorView, PublisherView
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^book/', BookView.as_view()),
        url(r'^author/', AuthorView.as_view()),
        url(r'^publisher/', PublisherView.as_view()),
    ]
    

    可以看到url系统拿到url后就去执行了视图函数的as_view()方法,那么这个方法到底做了什么事,我们先来看视图编写部分
    视图系统

    class BookView(views.View):
        def get(self,request):
            ret = Book.objects.all().values('title', 'publisher__name', 'author__name')
            l = {}
            for index, i in enumerate(ret):
                l[index] = i
                print(index,i)
            return JsonResponse(l)
    
    
    class PublisherView(views.View):
        def get(self,request):
            ret = Publisher.objects.all().values('name','address')
            print(ret)
            l = {}
            for i, index in enumerate(ret):
                l[i] = index
            return JsonResponse(l)
    
    
    class AuthorView(views.View):
        def get(self,request):
            ret = Author.objects.values('name','country','age')
            l = {}
            for i, index in enumerate(ret):
                l[i] = index
            print(l)
            return JsonResponse(l)
    

    大家知道,我们编写的CBV的视图类中是没有as_view方法的,所以as_view肯定是我们视图类继承的view.View类中的方法,我们接下来分析下源码

    View源码分析

    我们进去view源码看看

    找到as_view方法

        def as_view(cls, **initkwargs):
            """
            Main entry point for a request-response process.
            """
            for key in initkwargs:
                if key in cls.http_method_names:
                    raise TypeError("You tried to pass in the %s method name as a "
                                    "keyword argument to %s(). Don't do that."
                                    % (key, cls.__name__))
                if not hasattr(cls, key):
                    raise TypeError("%s() received an invalid keyword %r. as_view "
                                    "only accepts arguments that are already "
                                    "attributes of the class." % (cls.__name__, key))
    
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
            view.view_class = cls
            view.view_initkwargs = initkwargs
    
            # take name and docstring from class
            update_wrapper(view, cls, updated=())
    
            # and possible attributes set by decorators
            # like csrf_exempt from dispatch
            update_wrapper(view, cls.dispatch, assigned=())
            return view
    

    注意as_view返回了view方法,而路由系统是会执行这个view方法

            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
    

    view 返回了一个self.dispatch(request, *args, **kwargs),在看看这个方法做了什么

        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.
            // 判断请求的方法是否在http_method_names中http_method_names是包含允许请求方式的八大请求
            if request.method.lower() in self.http_method_names:
               // 然后判断类视图中是否有请求对应的方法例如get,否则执行报错
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
    

    总结

    CBV源码步骤:
    1、执行as_view方法,返回一个view函数,
    2、路由系统会执行view函数,会调用dispatch函数
    3、dispatch函数会根据requesrt.method请求的方法判断请求是否合理
    4、请求合理后会去判断请求对应的方法是否在视图函数类中
    5、执行相应的视图函数类的方法,例如请求方式为get,那么dispatch方法的返回就会执行视图的get方法

  • 相关阅读:
    为你的 Github 博客加个 CMS -「内容管理」
    Alpha、Beta、RC、GA、LTS等软件各个版本号的含义
    WPF圆形进度条
    初试WPF代码迁移Core WPF
    dumpbin查看(Exe,Dll)是32位还是64位
    Windows Live Writer使用SyntaxHighlighter代码着色插件
    C#调用EnumDevice获取设备信息
    C#获取设备(Audio和Video)名称 简单整理
    C# Winform 换肤
    C# Winform模仿百度日历
  • 原文地址:https://www.cnblogs.com/Kingfan1993/p/10108276.html
Copyright © 2011-2022 走看看