基于类的视图的实例变量是否持久?

时间:2012-08-16 19:29:32

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

我刚开始在django中使用基于类的视图。但是这个问题对我来说很困惑。我使用带有多线程开发服务器的django 1.4.1运行以下代码片段。

class TestView(TemplateView):
    template_name = 'test.html'
    count = 0
    mylist = [1, ]

    def get(self, request, *args, **kwargs):
        self.count += 1
        self.mylist.append(self.mylist[-1] +1)
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        context = super(TestView, self).get_context_data(**kwargs)
        context['count'] = self.count
        context['mylist'] = self.mylist
        return context

模板只输出上下文变量count和mylist。当调用此视图时,例如最多5倍的输出将如下所示:

count: 1
mylist: [1, 2, 3, 4, 5, ]

现在我很困惑。 django docs说,每个请求都有自己独立的类实例。

那么如何将mylist扩展到几个请求呢? 为什么count变量没有递增?

3 个答案:

答案 0 :(得分:1)

如果您需要多个请求可用的内容,则需要将其添加到会话中。伊瓦尔不是那个地方。对于线程安全性,as_view方法每次都返回一个全新的类实例,这不会受到同一类的任何其他实例上发生的任何其他实例的影响。这是设计,如果不是这样的话你会遇到很多问题。

答案 1 :(得分:0)

列表是可变的。整数是不可变的

您可以附加到列表中,它仍然是您班级的相同参考。但是当你执行self.count += 1时,每次都要创建一个新的int对象,这将成为该实例的范围。该值永远不会影响班级。

例如,如果您将其设置为:

count = [0]

def get(self):
    self.count[0] += 1

您会发现计数将在实例之间递增,因为您正在修改列表的成员,而不是每次都替换该对象。不是我推荐那个容器。只是一个例子。

您可以通过执行以下操作直接修改类:

count = 0

def get(self):
    self.__class__.count += 1

每次都会替换类级别的int对象。

但是我会非常小心地尝试在这样的线程之间保持类的数据。它不是线程安全的。只读数据并不存在问题,但要从一堆不同的线程中更改它可能会有问题。如果将数据存储在数据库中,情况会好很多。

答案 2 :(得分:0)

在每个请求上,创建一个视图并重新调用,而不了解先前的视图。要在多个视图中保留一些信息,您需要将其放在持久存储中,在Django中通常表示如果需要长期存储,则使用数据库,或者使用短期持久性会话。

此外,几乎不需要覆盖get(和post);你在那里所做的一切都可以用get_context_data方法完成。