2016-08-15 11 views
1

誰かがget_querysetをオーバーライドし、selfでクエリセットを参照してページを完全にキャッシュする理由を説明できますか?データベースの更新が行われるまでに5分以上待つ必要があります。get_querysetを無効にすると、データが古くなっているListViewで頭痛が発生する

私は各オブジェクトに一時的な値を保存して、それをテンプレートに渡そうとしています。

例3ではうまく動作していますが、実際には動作させるために何をしたのか分かりませんので、どんな洞察も素晴らしいでしょう!

例1:数分間キャッシュが、OK 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' 今は動作しません

メソッドを含めずに自動的にクエリセットを呼び出すだけの場合は、キャッシュやデータベースの更新はすぐに表示されますが、一時データはテンプレートに到達しません。 クラスAppointmentListView(リストビュー):

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

あなたはListView.get_queryset実装が使用されることを意味し、get_querysetを上書きしませんでした。

DjangoのListView.get_querysetは、評価する前にquerysetをコピーしています。そのため、「キャッシング」が表示されません。しかし、クエリーセットがコピーされるので、forループのエフェクトは破棄されます。

例3

これは、一般的に、あなたのコードを書くための正しい方法です。 「キャッシング」の動作を見たくない場合は、このようなメソッドを記述する必要があります。

+0

偉大な答え、感謝デレク。 –

関連する問題