Django Class 基于视图:理解视图中的参数 class

Django Class Based Views: Understanding the arguments in the view class

通读 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 class only方法。 as_view 调用 view 方法,该方法用 self= cls(**initkwargs) 实例化一个 View 对象,然后 __init__ 运行。

我对弄清楚 view 方法采用的 **kwargs 和实例化 class 时使用的 **initkwargs 之间的区别感到困惑。我假设 view 方法通过 **kwargs 传递所有参数...那么为什么 self= cls(**initkwargs) 行不写成 self = cls(**kwargs)?

**initkwargs**kwargs有什么区别?

代码只是明确区分从 urlconf 传递到视图实例化 class 本身的硬编​​码 kwargs 和从 URL 当实际调用视图时。

as_view calls the view method which instantiates a View object with self= cls(**initkwargs) and then the __init__ runs.

实际上不,这没有发生。 as_view 没有调用 view 函数(view 不是方法),as_view 创建 view 函数并 returns 它,所以它可以稍后调用。 initkwargs 在处理 url 模式时传递给 as_view,当 URL 调度程序调用它时 kwargs 在检索某些 url 时传递到视图.这就是为什么 kwargsinitkwargs 不是一回事。