搜索

首页  >  问答  >  正文

python - django源码探究,as_view()的具体分发过程?

最近在学习django的类视图,就打开源码学习下,但是对基类View的as_view方法不太理解,先把源码贴上来:

    @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))

        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

因为最后涉及View的另外的一个方法dispatch,我也贴出这个方法源码:

    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方法时,会把请求时的request方法自动对应到相应的类方法上,比如request的get方法对应到类视图的get方法。

但是我看完源码的理解是:as_view仅仅能自动对应get和post(具体的request方法在类属性当中有个列表:http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'])等方法,如果我在类视图定义了自己的方法,那as_view并不能把我自定义的方法对应起来

但是,同样是类视图,ListView当中却有get_queryset方法,那ListView在调用as_view方法时会自动调用这个get_queryset方法吗(它并不是request的方法是吧?)?

代码哪里提到了这个过程呢?

望大神指教~抱拳

阿神阿神2788 天前569

全部回复(1)我来回复

  • PHP中文网

    PHP中文网2017-04-18 10:36:42

    dispath方法里就是根据request的方法寻找class view对应的函数处理:handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

    ListView中的get_queryset方法是别的函数调用的

    回复
    0
  • 取消回复