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