问题描述
在这个例子中,我经常看到** kwargs传递,没有提到它来自哪里: 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):
#首先调用基本实现以获取上下文
context = super(PublisherDetailView,self).get_context_data( ** kwargs)
#添加所有书籍的查询集
上下文['book_list'] = Book.objects.all()
返回上下文
** kwargs是从哪里神奇地拔出来的?
此外,这不是一个额外的工作,只是为了添加一个单一的字典对象?
查看 SingleObjectMixin
的基本实现(原始 get_context_data
)。
它只是返回 ** kwargs
作为上下文(一个字典),同时添加正在编辑的对象键指定。
def get_context_data(self,** kwargs):
context = kwargs
context_object_name = self.get_context_object_name(self.object)
如果context_object_name:
上下文[context_object_name] = self.object
返回上下文
在 DetailView
中,kwargs从任何调用它/通过这些kwargs的神奇地采摘。在你的情况下,这将是 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)
它被许多视图类使用(如 render_to_response(self.get_context_data)
),它将原始上下文
字典传递给 self .response_class
这是默认情况下 django.template.TemplateResponse
。
TemplateResponse
知道如何渲染自己,在其 resolve_context
函数中,最后将字典转换为 django。 template.Context
你真的可以从原始方法一直跟随源。
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.
这篇关于Django通用的基于类的视图示例:** kwargs来自哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!