基于类的通用视图额外上下文

时间:2013-02-11 17:19:20

标签: django

在基于类的视图之前,有一个extra_context关键字可以在urlsconf中传递。 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原则,做两次。

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

由于

5 个答案:

答案 0 :(得分:16)

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

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

但为了让我的生活更轻松,我接受了@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 dict传递给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'),

答案 1 :(得分:9)

我想这不是那么简单,但它仍然只有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等,并将它们导入到您执行的每个项目中。

答案 2 :(得分:8)

阅读上面的答案,似乎这种方法在解决问题的同时,本质上是一种破坏旧功能的方法。一个小小的谷歌搜索带来generic class-based views page,其中包含标题为&#34; adding extra context的部分。&#34;总而言之,解决方案只是实现您自己的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

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

答案 3 :(得分:0)

完全感谢mogga对已接受答案的评论:

  

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

因此,获取它的方法是升级到2.X(如果尚未安装的话)。

答案 4 :(得分:0)

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