as_view in django源码分析

asdfd

一、基于类的视图

基于函数的视图,我想不用多说了吧。
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r’^$’, views.yourfuncview, name=‘name’)在这里插入图片描述

接下来我们要重点关注的是基于类的视图,看看它是如何使用的
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的源码

总体思路:把视图函数的逻辑定义到类中,再通过继承的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 方法。类视图的核心思想就是把视图函数的逻辑定义到类的方法里面去,然后在函数中实例化这个类,通过调用类的方法实现函数逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你抱着的是只熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值