【问题标题】:Django passing variables to templates from class based viewsDjango 将变量从基于类的视图传递给模板
【发布时间】:2013-08-16 11:19:08
【问题描述】:

如果我有一个基于类的视图,像这样,

class SomeView (View):
    response_template='some_template.html'
    var1 = 0
    var2 = 1

    def get(self, request, *args, **kwargs):
        return render_to_response(self.response_template, locals(), context_instance=RequestContext(request))

我的问题是,在模板some_template.html 中,我如何访问var1var2?据我了解,locals() 只是将所有局部变量转储到模板中,到目前为止效果很好。但是这些其他变量在技术上不是“本地的”,它们是一个类的一部分,那么我该如何传递它们呢?

谢谢!

【问题讨论】:

    标签: django class django-templates django-views django-class-based-views


    【解决方案1】:

    更简洁的方法是复制 Django 的模板视图:

    class TemplateView(TemplateResponseMixin, ContextMixin, View):
        """
        A view that renders a template.  This view will also pass into the context
        any keyword arguments passed by the url conf.
        """
        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    

    然后将其添加到 get_context_data 函数中。或者您可以简单地使用 TemplateView,它允许您指定模板名称,然后您可以覆盖 get_context_data 函数:

    class SomeView(generic.TemplateView):
        var1 = 0
        var2 = 1 
        template_name = 'some_template.html'
    
        def get_context_data(self, **kwargs):
            context = super(SomeView, self).get_context_data(**kwargs)
            context.update({'var1': self.var1, 'var2': self.var2})
            return context
    

    编辑

    Django 具有通用视图,您可以将其用于各种事情,我强烈建议您查看docs 以获取它们的完整列表,这些通用视图具有您可以覆盖的功能以执行自定义操作默认不支持。在您的情况下,您只需要一个带有上下文变量的模板,这意味着您将 TemplateView 子类化并提供 template_name,然后最后您可以覆盖 get_context_data 函数以添加您的上下文数据,这就是它的全部内容,第二部分在您的情况下,您只需要代码。

    【讨论】:

    • 我确定你写的是一个很好的解决方案,但我不太明白...... Django 中有太多东西我还不太明白。这个框架有点复杂
    • 我已经更新了我的答案,只是为了为您指明正确的方向以供将来使用:)
    【解决方案2】:

    get 方法中将self.var1self.var2 添加到上下文中:

    class SomeView (View):
        response_template='some_template.html'
        var1 = 0
        var2 = 1
    
        def get(self, request, *args, **kwargs):
            context = locals()
            context['var1'] = self.var1
            context['var2'] = self.var2
            return render_to_response(self.response_template, context, context_instance=RequestContext(request))
    

    注意:render_to_response() 在 Django 3.0 及更高版本中被删除(改用render())。

    另外,我不确定将locals() 作为上下文传递给模板是一种好习惯。我更喜欢显式构造传递到模板中的数据 = 只传递模板中真正需要的数据。

    【讨论】:

    • 是不是因为 locals() 可能包含很多可能污染模板中命名空间的随机内容?介绍一大堆我永远不会使用的东西?还是出于其他原因?安全??
    • 正如Zen of Python 所说:Explicit is better than implicit。而且我认为查看和调试更简洁。
    • 我同意使用 locals() 是不好的做法。你可以是显式的,只需使用 get_context_data() 覆盖——在基于类的视图中,这被认为是向模板传递变量的标准方式。
    • render_to_response() 在 Django 3.0 中被移除。如果您使用的是 Django 3.0 或更高版本,则应该使用 render()。
    【解决方案3】:

    您可以看到here 有两种方法。第一个,你可以像这样声明一个名为get_context_data的函数:

    def get_context_data(self, **kwargs):          
        context = super().get_context_data(**kwargs)                     
        new_context_entry = "here it goes"
        context["new_context_entry"] = new_context_entry
        return context
    

    如果您使用的是 Django 2.x,您也必须在 get_context_data 中传递 *args

    第二种方法是在视图的某个函数中修改extra_context变量:

    self.extra_context["another_one"] = "here goes more"
    

    【讨论】:

      【解决方案4】:

      为了在函数中传递你的类标签变量,你需要引用self,它是一个新创建的对象。正如我们所知,要访问类中的任何变量,我们都需要引用它的对象。否则会被抓到全局名'your variable' is not defined

      作为你的例子,你可以这样做

      class YourView(genericView):
          template_name='your_template.html'
          var1 = 12
          var2 =1
      
          def get(self, **kwargs):
              context = locals()
              context['var1'] = self.var1
             context['var2'] = self.var2
             return context
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-02
        • 2011-06-03
        • 1970-01-01
        • 2020-12-23
        • 2015-05-23
        • 1970-01-01
        • 2019-04-03
        相关资源
        最近更新 更多