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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With