【问题标题】:class based generic views extra context基于类的通用视图额外上下文
【发布时间】:2013-01-26 20:39:30
【问题描述】:

在基于类的视图之前,有一个 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 原则,做两次。

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

谢谢

【问题讨论】:

    标签: django


    【解决方案1】:

    想了很多之后,唯一的答案是否定的,该功能已被删除。

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

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

    【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 问题不在于如何将通用视图子类化,问题在于该功能已被删除。
    • 是的,我猜。你的问题我真的没有答案。我不知道为什么它被删除了。
    • 这会起作用,但是有一条旧的 Django 规则“不要将任何东西传递给 url 文件中的 url 视图!”这会让它变慢!来自两勺 django(一本书)的资源
    【解决方案3】:

    阅读上述答案,似乎这种方法在解决问题的同时,本质上是一种恢复旧功能的技巧。用谷歌搜索了一下generic class-based views page,其中包含一个标题为“adding extra context”的部分。在这里总结一下,解决方案只是实现您自己的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 来包含各种上下文参数,你可以利用基于类的视图提供的所有功能,同时仍然提供自定义的上下文内容.

    【讨论】:

    • @fariza - 代码相同,不同之处在于方法。接受的答案使用上面的代码将数据传递给as_view(如果我理解正确的话)。这建议使用代码直接将参数传递给模板,而不需要修改urls.py中的任何内容。
    • 最初的问题是关于删除的功能以及如何将其恢复。该功能意味着通用视图接受来自 urls.py 的额外上下文
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-01-15
        • 1970-01-01
        • 1970-01-01
        • 2013-05-21
        • 1970-01-01
        • 2011-08-14
        • 2015-07-16
        • 1970-01-01
        • 2021-11-20
        相关资源
        最近更新 更多