2013-10-31 9 views
32

これら二つの作品は一見同じです:get_queryset()メソッドを使用するか、queryset変数を設定しますか?コードの

class IndexView(generic.ListView): 
    template_name = 'polls/index.html' 
    context_object_name = 'latest_poll_list' 
    queryset = Poll.active.order_by('-pub_date')[:5] 

class IndexView(generic.ListView): 
    template_name = 'polls/index.html' 
    context_object_name = 'latest_poll_list' 

    def get_queryset(self): 
     return Poll.active.order_by('-pub_date')[:5] 

は、それらの間のいずれかの違いはありますか?それが:

どのようなアプローチが良いですか?または、queryset変数を設定すると、get_querysetメソッドをオーバーライドするよりも優れていますか?およびその逆。

答えて

47

をメソッドを使用してget_querysetさは同じ効果を持っています。私はそれほど冗長ではないので、設定を少しでも好むでしょう(queryset)。

querysetを設定すると、サーバーの起動時にクエリーセットが1回だけ作成されます。一方、すべての要求に対してget_querysetメソッドが呼び出されます。

つまり、get_querysetは、クエリを動的に調整する場合に便利です。 get_querysetが有用である別の例では、呼び出し可能に基づいてフィルタリングしたいとき、例えば、今日の世論調査を返さある

class IndexView(generic.ListView): 
    def get_queryset(self): 
     """Returns Polls that belong to the current user""" 
     return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5] 

class IndexView(generic.ListView): 
    def get_queryset(self): 
     """Returns Polls that were created today""" 
     return Poll.active.filter(pub_date=date.today()) 
たとえば、あなたは、現在のユーザーに属するオブジェクトを返すことができます

querysetを設定して同じことを実行しようとすると、date.today()はビューがロードされたときに1度だけ呼び出され、しばらくするとビューに間違った結果が表示されます。

class IndexView(generic.ListView): 
    # don't do this! 
    queryset = Poll.active.filter(pub_date=date.today()) 
+2

あなたは 'get_queryset'' self.model.objects.filter(...) 'に書き込むこともできます。自分のリストビューを継承する場合は、 'super(YourListViewExtendingSomeOtherLV、self).get_queryset()。filter(...)'を参照することを忘れないでください。 – andi

4

クエリセットの属性は、内部的に使用常にquerysetをオーバーライドし、あなたの例では(あなたは、多くの場合、例えば、要求またはセッションVARSに基づいてカスタムクエリを実行する必要があります)

8

他の回答には、プロセスの起動時にqueryset属性が評価されているという事実の重要な意味を逃しました。クエリーセットを作成するだけではないので、実際にはをスライスしてとすると、クエリはとなり、その時点でと評価されます。つまり、その時点で上位5つの投票しか取得できず、別の投票を作成しても、プロセスが再開されるまで更新されません。

これは、正確にget_queryset()を使用する必要がある場合です。

+0

[the docs](https://docs.djangoproject .com/en/1.8/ref/models/querysets /#when-querysets-are-evaluate)、評価されていないクエリセットをスライスしても、スライス構文の 'step'パラメータを使用しない限り、評価されません。 – Alasdair

1

モデルとクエリーセットは非常によく似ていますが、クエリーセットの値が指定されている場合は、モデルのものよりも優先されます。

モデルは、このビューが表示するオブジェクトのタイプです。

Djangoのドキュメントから:

モデル:

このビューモデル:このビューが (最後の5つのインスタンスが作成されたEX)が表示されますどのような特定のインスタンスコントロールget_queryset

のオーバーライドのデータが表示されます。 モデル= Fooを指定することは、と実質的に同じです。queryset = Foo.objects.all()ここで、オブジェクトはFooのデフォルトマネージャーを表します。

クエリセット:

オブジェクトを表すクエリセット。 querysetの値は、モデルに指定された値よりも優先されます。

get_queryset:

get_queryset()このビューが表示されるというオブジェクトを取得するために使用されるクエリセットを返します。デフォルトでは、get_queryset()はqueryset属性が設定されている場合はその値を返し、そうでない場合はmodel属性のデフォルトマネージャーでall()メソッドを呼び出してQuerySetを構築します。

関連する問題