可以在基于Django类的视图中设置实例变量吗?

时间:2012-07-12 09:20:59

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

我尝试了Django基于类的视图(CBV)。

class BlahView(TemplateView):
    template_name = 'blah/blah.html'
    def get_context_data(self, **kwargs):
        #code...

    def get(self, request, **kwargs):
        #more code...

现在,我知道我可以从self.request获取请求参数。现在说我要解析这些请求参数并将它们存储在类中。我可以将它们存储在self.xxx中吗?现在,显然基于类的工作方式,这似乎很简单。

但我无法弄清楚控制的流程,看看ViewTemplateView的超类)的定义。 source提及as_view()为“入口点”

我想在get_context_data()的开头设置我的实例变量,但在那里做初始化似乎不对。

我可以为我的CBV定义__init__()吗? 如果是这样,是否会出现线程问题或多个页面访问可能与我的解析数据的全局实例一起工作?

我知道这听起来有点乱,但我对CBV中的代码流感到有些困惑。

2 个答案:

答案 0 :(得分:43)

根据django.views.generic.base.View.as_view的{​​{3}}:

  • 在django启动上,as_view()返回一个函数view称为
  • 根据请求view() 被称为,它会实例化该类并调用dispatch()
  • 类实例是线程安全的

根据django.views.generic.base.View.__init__的{​​{3}},此时请求对象超出了范围,因此您无法在自己的构造函数重载中解析它。

但是,您可以解析请求并在django.views.generic.base.View.dispatch的重载中设置类视图实例属性,根据the source这是安全的:

class YourView(SomeView):
    def dispatch(self, request, *args, **kwargs):
        # parse the request here ie.
        self.foo = request.GET.get('foo', False)

        # call the view
        return super(YourView, self).dispatch(request, *args, **kwargs)

答案 1 :(得分:2)

@jpic提供了一个很好的答案。受其启发,我想参考作者声称的以下blog post

  

...我们无法覆盖视图,因为这样做会需要覆盖   as_view()。覆盖dispatch()很吸引人(我做了什么   最初当我提出这个演讲时)因为它提供单一的   这样做的简单的地方,但这违背了dispatch()的逻辑。   相反,最好在get()的覆盖中调用set_account()   和post()。 ...

因此,可以覆盖getpost方法并设置任何self.whatever个变量。感觉有些干净。