14

在基于类的视图之前,有一个可以在 urlsconf 中传递的 extra_context 关键字。 https://docs.djangoproject.com/en/1.3/topics/generic-views/#adding-extra-context

现在使用基于类的通用视图,如果我们想做同样的事情,我们必须子类化通用视图 https://docs.djangoproject.com/en/1.3/topics/class-based-views/#adding-extra-context

如果我们想要一些简单的东西,我们正在使用通用的 CreateView 和 UpdateView。这种方法将强制对以前微不足道的东西进行子类化。更重要的是,我们必须打破 DRY 原则,做两次。

为什么会这样?为什么我们不能将额外的上下文直接传递给模板有什么原因吗?

谢谢

4

5 回答 5

24

经过太多思考,唯一的答案是否定的,该功能已被删除。

并且文档没有提到“已删除的功能”,也没有解释为什么会这样。

但是为了让我的生活更轻松,我接受了@aidan 的建议并进行了一些修改

class ExtraContext(object):
    extra_context = {}

    def get_context_data(self, **kwargs):
        context = super(ExtraContext, self).get_context_data(**kwargs)
        context.update(self.extra_context)
        return context

class ExtraListView(ExtraContext, ListView):
    pass

class ExtraDetailView(ExtraContext, DetailView):
    pass

class ExtraUpdateView(ExtraContext, UpdateView):
    pass

class ExtraCreateView(ExtraContext, CreateView):
    pass 

class ExtraDeleteView(ExtraContext, DeleteView):
    pass

class ExtraCloneView(ExtraUpdateView):
    def post(self, request, *args, **kwargs):
       return ExtraCreateView.as_view(model=self.model,
                              template_name=self.template_name,
                              extra_context=self.extra_context)(request, *args, **kwargs)    

现在我有了可以直接在 URLSconf 中使用的半通用视图,并将 extra_context 字典传递给 as_view() 调用

url(r'^camera/(?P<pk>\d+)/$', 
    views.ExtraDetailView.as_view(model=models.Camera,
                               extra_context={'action_type': 'detail', 'mod_name' : 'camera'},
                               template_name='cameras/camera_detail.html'), 
    name='camera_detail'),
于 2013-02-12T16:36:44.683 回答
15

我想这不是那么简单,但它仍然只有 5 行代码 -

class MyView(CreateView):
    def get_context_data(self, *args, **kwargs):
        context = super(MyView, self).get_context_data(*args, **kwargs)
        context['my_additional_context'] = my_object
        return context

如果你真的想要基于类的视图的功能,那么也许你可以扩展类来添加它 -

class MyCreateView(CreateView)
    additional_context = {}
    def get_context_data(self, *args, **kwargs):
        context = super(MyView, self).get_context_data(*args, **kwargs)
        context.append(self.additional_context)
        return context

然后在您的 url_conf 中使用它 -

urlpatterns = patterns('',
    #....
    (r'^my_url/$', MyCreateView.as_view(additional_context={'my_addional_context': my_object})),
)

您可以编写自己的 CreateView、DetailView、ListView 等并将它们导入到您所做的每个项目中。

于 2013-02-11T18:02:09.643 回答
8

阅读上述答案,似乎这种方法在解决问题的同时,本质上是一种恢复旧功能的技巧。稍微用谷歌搜索一下,出现了通用的基于类的视图页面,其中包含一个标题为“添加额外上下文”的部分。在这里总结一下,解决方案只是实现您自己的版本,get_context_data()其中包含您要传递给模板的变量:

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

class PublisherDetail(DetailView):

    model = Publisher

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

这里最大的好处是你不需要“破解”urls.py来包含各种上下文参数,你可以利用基于类的视图提供的所有功能,同时仍然提供自定义的上下文内容。

于 2015-02-16T02:40:28.133 回答
1

只需使用extra_context,这是在 2017 年添加的(https://github.com/django/django/pull/8671

于 2020-07-28T21:28:14.807 回答
0

完全归功于 mogga 对已接受答案的评论:

2.0 带回了 extra_context docs.djangoproject.com/en/2.1/ref/class-based-views/… – mogga

所以获得它的方法是升级到 2.X,如果你还没有的话。

于 2019-01-12T16:06:51.160 回答