【问题标题】:Are Instance variables of class-based-views persistent?基于类的视图的实例变量是否持久?
【发布时间】:2012-08-16 19:29:31
【问题描述】:

我刚刚开始在 django 中使用基于类的视图。但是有一个问题让我很困惑。我使用带有多线程开发服务器的 django 1.4.1 运行了以下代码 sn-p。

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 文档说,每个请求都有自己的单独的类实例。

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

【问题讨论】:

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


    【解决方案1】:

    如果您需要一些可用于多个请求的内容,则需要将其添加到会话中。 ivar 不适合那样做。为了线程安全,as_view 方法每次都返回一个全新的类实例,这不受同一类的任何其他实例上发生的任何其他事情的影响。这是设计使然,如果不是这样,你会遇到很多问题。

    【讨论】:

      【解决方案2】:

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

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

      例如,如果您这样设置:

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

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

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

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

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

      但我会非常小心地尝试像这样在线程之间的类上持久化数据。它不是线程安全的。只读数据并没有真正的问题,但是从一堆不同的线程中更改它可能会出现问题。如果您将数据存储在数据库中会更好。

      【讨论】:

        【解决方案3】:

        在每次请求时,都会创建一个视图并重新调用,而无需了解先前的视图。要在多个视图中保留一些信息,您需要将其放入持久存储中,在 Django 中,如果您需要长期存储,这通常意味着数据库,或者用于短期持久性的会话。

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

        【讨论】:

          猜你喜欢
          • 2015-05-08
          • 1970-01-01
          • 1970-01-01
          • 2012-07-12
          • 2011-03-04
          • 2019-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多