0

Reading through the source code for View Class

Source code:

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

My understanding is that when the urlconf is loaded, the as_view class only method is called. as_view calls the view method which instantiates a View object with self= cls(**initkwargs) and then the __init__ runs.

I get confused with figuring out the difference between **kwargs which is taken by the view method, and **initkwargs which are used while instantiating a class. I assume the view method is passed all arguments through the **kwargs...then why isn't the self= cls(**initkwargs) line written as self = cls(**kwargs)?

What's the difference between **initkwargs and **kwargs?

Jcb Rb
  • 61
  • 7

2 Answers2

3

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

Actually no, that's not happening. as_view is not calling view function (view is not a method), as_view creates view function and returns it, so it can be called later. initkwargs are passed to as_view when urlpatterns are processed, kwargs are passed into view when URL dispatcher calls it when certain url is retrieved. That's why kwargs and initkwargs are not same thing.

GwynBleidD
  • 20,081
  • 5
  • 46
  • 77
  • Are the values of `**initkwargs` and `**kwargs` different? The URL dispatcher passes `view(request, **args, **kwargs)` the arguments contained in the URL as **kwargs, correct? Then what is/are the value(s) of `**initkwarg`? Are they also found in the URL? Or do they come from something else? – Jcb Rb Feb 27 '15 at 20:27
  • Nevermind I understand. It's possible to subclass the base view class with TemplateView for example. If you do this, you can override the default Template Name by passing it to as_view. Then, arguments from the URL are further added into the view function – Jcb Rb Feb 27 '15 at 20:50
0

The code is just making an explicit distinction between the hard-coded kwargs you're passing from the urlconf to the instantiation of the view class itself, and the dynamic kwargs you're passing from the URL when the view is actually called.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895