as_view in django源码分析

asdfd

as_view in django源码分析

  • 一、基于类的视图
  • 二、as_view的源码
    • 总体思路:把视图函数的逻辑定义到类中,再通过继承的View类的as_view类方法返回一个名叫view函数,然后再执行这个view函数,通过在view中实例化自定义的类,再配合从前端的请求方式(get/post)来映射(dispatch)到自定义类的get或者post方法中去。通过类来定义逻辑的好处就是代码重用!!!

一、基于类的视图

基于函数的视图,我想不用多说了吧。
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r’^$’, views.yourfuncview, name=‘name’)as_view in django源码分析_第1张图片

接下来我们要重点关注的是基于类的视图,看看它是如何使用的
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r’^$’, Home.as_view(), name=‘home’)
as_view in django源码分析_第2张图片

二、as_view的源码

总体思路:把视图函数的逻辑定义到类中,再通过继承的View类的as_view类方法返回一个名叫view函数,然后再执行这个view函数,通过在view中实例化自定义的类,再配合从前端的请求方式(get/post)来映射(dispatch)到自定义类的get或者post方法中去。通过类来定义逻辑的好处就是代码重用!!!

    @classonlymethod
    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))
        #2.然后执行这个函数,并传入request,等从前端传过来的参数
        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=())
        # 1.执行 as_view()后返回了这个view
        return view
    
    # 3.最后根据是get、post请求执行对应的定义在自己编写的get、post方法
    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)

调用顺序: as_view --> view --> dispatch

  1. 可以看出as_view实际上是一个闭包,他的作用就是做一些检验工作,再返回view方法
  2. 而view方法的作用是给请求对象补充三个参数,并调用dispatch方法处理
  3. dispatch方法查找到指定的请求方法,并执行相应代码块

总结
现在我们已经明白了类视图的基本结构,其主要功能就是根据 HTTP 请求方法的不同做出相应处理,具体的实现为 dispatch 方法。类视图的核心思想就是把视图函数的逻辑定义到类的方法里面去,然后在函数中实例化这个类,通过调用类的方法实现函数逻辑。

你可能感兴趣的:(django)