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

far*_*iza 11 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原则,做两次.

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

谢谢

far*_*iza 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)    
Run Code Online (Sandbox Code Playgroud)

现在我有半通用的视图,我可以直接在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'),
Run Code Online (Sandbox Code Playgroud)

  • 2.0 带回 `extra_context` https://docs.djangoproject.com/en/2.1/ref/class-based-views/mixins-simple/#contextmixin (2认同)

Aid*_*wen 11

我想这不是那么简单,但它仍然只有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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

然后在你的url_conf中使用它 -

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

您可以编写自己的CreateView,DetailView,ListView等,并将它们导入到您执行的每个项目中.


eyk*_*nal 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
Run Code Online (Sandbox Code Playgroud)

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