2016-08-15 52 views
1

有人可以解釋爲什麼覆蓋get_queryset和通過self引用查詢集完全緩存頁面嗎?在對數據庫顯示進行更新之前,我需要等待5分鐘或更長時間。覆蓋get_queryset導致ListView中的緩存頭痛,其中數據仍然陳舊

我試圖保存一個臨時值到每個對象,並將其傳遞給模板。

我已經在示例3中使用了一切正常和花哨的工作,但並不真正瞭解我做了什麼來使其工作,所以任何洞察力都會很棒!

例1:緩存幾分鐘,但r.css = 'ABC' 工作確定

class AppointmentListView(ListView): 
    qs = Appointment.objects.prefetch_related('client', 'patients') 

    def get_queryset(self): 
     for r in self.qs: 
      r.css = 'abc' #<-passes temp value to template ok 
     return self.qs 

例2:沒有緩存的問題,但r.css = 'ABC',現在不工作

如果我沒有包含方法並且只是自動調用queryset,則不會立即顯示緩存和數據庫更新,但是我的臨時數據不會到達模板。 類AppointmentListView(ListView控件):

queryset = Appointment.objects.prefetch_related('client','patients') 

    for r in queryset: 
     r.css = 'abc' #<- NOT passed to template 

例3:沒有緩存的問題,r.css = 'ABC' 工作正常

最後,如果我把一切的方法,這一切工作正常 - 溫度數據到達模板並且沒有緩存。

class AppointmentListView(ListView): 

    def get_queryset(self): 
     qs = Appointment.objects.prefetch_related('client','patients') 
     for r in qs: 
      r.css = 'abc' #<-passes to template ok 

     return qs 

回答

1

您看到的行爲是Python如何評估您的代碼。下面是一個簡單的例子,解釋你所看到的。

import random 

class Example1(object): 
    roll = random.randint(1, 6) # this is evaluated immediately! 
    def get_roll(self): 
     return self.roll 

ex1 = Example1() 

# the call below always returns the same number! 
# (until Python re-interprets the class) 
ex1.get_roll() 

如果鍵入上面的代碼轉換爲Python解釋器,你會發現,ex1.get_roll()總是返回相同的號碼!

Example1.roll被稱爲類或靜態變量。這些僅在定義類時評估一次。

class Example2(object): 
    def get_number(self): 
     roll = random.randint(1,6) 
     return roll 

Example2中,每次生成新的隨機數get_roll方法被調用。

對於你的問題中列出的例子:

例1

qs是一個類變量,因此僅被評估一次(這就是爲什麼你看到的「緩存」的行爲)。隨後調用get_queryset返回最初評估的相同qs變量。

實施例2

你沒有覆蓋get_queryset,這意味着ListView.get_queryset實現,則使用。

Django的ListView.get_queryset在評估之前複製了queryset - 這就是爲什麼你沒有看到「緩存」。但是,由於查詢集已被複制,因此for循環的效果將被丟棄。

例3

這通常是編寫代碼的正確方法。如果你不想看到「緩存」行爲,你應該寫這樣的方法。

+0

很好的答案,謝謝德里克。 –