Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django generic class-based view example: where does **kwargs come from?

Tags:

django

In the examples, I constantly see **kwargs passed around with no mention of where it is coming from:

from django.views.generic import DetailView
from books.models import Publisher, Book

class PublisherDetailView(DetailView):

    context_object_name = "publisher"
    model = Publisher

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(PublisherDetailView, self).get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

Where is **kwargs being magically plucked from?

Also, does this not seem like a whole lot of extra work just to add a single dictionary object?

like image 920
wiener_patrol Avatar asked Oct 27 '11 04:10

wiener_patrol


2 Answers

Look at the base implementation of SingleObjectMixin (the "original" get_context_data).

It simply returns **kwargs as the context (a dictionary), while adding the object being edited with the key specified.

 def get_context_data(self, **kwargs):
            context = kwargs
            context_object_name = self.get_context_object_name(self.object)
            if context_object_name:
                context[context_object_name] = self.object
            return context

In a DetailView, the kwargs are "magically plucked" from whatever is calling it / passing in those kwargs. In your case, that would be BaseDetailView.get().

class BaseDetailView(SingleObjectMixin, View):
        def get(self, request, **kwargs):
            self.object = self.get_object()
            context = self.get_context_data(object=self.object)
            return self.render_to_response(context)

It's later used by many view classes (as in render_to_response(self.get_context_data)) which passes the raw context dictionary to self.response_class which is by default django.template.TemplateResponse.

TemplateResponse knows how to render itself, and in its resolve_context function, finally converts the dictionary to a django.template.Context

You really can follow the source all the way from the original method all the way down.

like image 64
Yuji 'Tomita' Tomita Avatar answered Oct 17 '22 13:10

Yuji 'Tomita' Tomita


The kwargs are generated in the URLConf. For example this will populate the pk item:

urlpatterns = patterns('',
    (r'^authors/(?P<pk>\d+)/$', AuthorDetailView.as_view()),
)

The call is via the view function in View.as_view and then through View.dispatch which calls TemplateView.get.

like image 20
Udi Avatar answered Oct 17 '22 14:10

Udi