Django泛型基于类的视图示例:**kwargs从何而来?



在示例中,我经常看到**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):
        # 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

**kwargs被魔法般地从哪里拔出来了?

另外,仅仅为了添加一个字典对象,这看起来不像是一大堆额外的工作吗?

查看SingleObjectMixin的基本实现("原始"get_context_data)。

它简单地返回**kwargs作为上下文(一个字典),同时使用指定的键添加正在编辑的对象。

 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

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))使用,它将原始context字典传递给self.response_class,默认为django.template.TemplateResponse

TemplateResponse知道如何呈现自己,并在其resolve_context函数中,最终将字典转换为django.template.Context

你真的可以按照源代码从原始方法一直到下。

在URLConf中生成kwargs。例如,这将填充pk项:

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

调用通过View.as_view中的view函数,然后通过View.dispatch调用TemplateView.get

最新更新