2012-08-16 55 views
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文檔說,每個請求都有它自己的單獨的類實例。

那麼它是如何能夠在數請求延長MYLIST? 爲什麼計數變量沒有增加?

回答

0

列表是可變的。整型是不變的

您可以附加到一個列表,它仍然是你的類相同的參考。但是當你做self.count += 1時,你每次都創建一個新的int對象,這成爲該實例的範圍。該值從不影響班級。

如果,例如,您可以將它像這樣:

count = [0] 

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

你會發現數將實例之間的遞增,因爲要修改的列表中的一員,而不是代替每個對象時間。不是我推薦那個容器。只是一個例子。

你可以通過專門做這樣的事情直接修改類:

count = 0 

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

這將取代每次一流水平的int對象。

但我會非常小心,努力堅持下去的這樣的線程之間的類數據。它不是線程安全的。只讀數據並沒有真正的問題,但要從一堆不同的線程中改變它可能會有問題。如果將數據存儲在數據庫中會更好。

1

如果需要可在多個請求的東西,你需要將它添加到會話中。伊娃不是那個地方。對於線程安全性來說,as_view方法每次都會返回一個全新的類實例,這不會受到同一類的任何其他實例上發生的其他任何事情的影響。這是由設計,如果不是這種情況,你會遇到很多問題。

0

對於每個請求,都會創建並重新調用一個視圖,但不知道以前的視圖。爲了在多個視圖中保留一些信息,你需要把它放在一個持久存儲器中,這在Django中通常意味着要麼是數據庫,要麼是需要長期存儲的數據庫,或者是用於短期持久化的會話。

此外,幾乎沒有必要重寫get(和post);您在那裏所做的一切都可以在get_context_data方法中完成。