基于Django类的视图:了解视图类中的参数

时间:2015-02-27 17:17:32

标签: django django-templates django-class-based-views django-generic-views

阅读View Class

的源代码

源代码:

class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
"""

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

def __init__(self, **kwargs):
    """
    Constructor. Called in the URLconf; can contain helpful extra
    keyword arguments, and other things.
    """
    # Go through keyword arguments, and either save their values to our
    # instance, or raise an error.
    for key, value in six.iteritems(kwargs):
        setattr(self, key, value)

@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

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)

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
        extra={
            'status_code': 405,
            'request': request
        }
    )
    return http.HttpResponseNotAllowed(self._allowed_methods())

我的理解是,当加载urlconf时,只调用as_view类方法。 as_view调用view方法,该方法使用self= cls(**initkwargs)实例化View对象,然后运行__init__

我很难弄清楚**kwargs方法所采用的view与实例化类时使用的**initkwargs之间的区别。我假设view方法通过**kwargs传递了所有参数...那么为什么self= cls(**initkwargs)行不是self = cls(**kwargs)

**initkwargs**kwargs之间的区别是什么?

2 个答案:

答案 0 :(得分:1)

  

as_view调用view方法,该方法使用View实例化self= cls(**initkwargs)对象,然后运行__init__

实际上不,那没有发生。 as_view未调用view函数(view不是方法),as_view创建view函数并返回它,因此可以稍后调用它。在处理urlpatterns时,initkwargs会传递给as_view,当检索到某个网址时,当URL调度程序调用它时,会将kwargs传递到视图中。这就是kwargsinitkwargs不同的原因。

答案 1 :(得分:0)

代码只是明确区分了你从urlconf传递到视图类本身的实例化的硬编码kwargs,以及你在从URL传递的动态kwargs。视图实际上被称为。