2009-06-02 16 views
6

datetimeフィールドで順序付けられたFooモデルから最新の5行をフェッチします。次のステップにおいてdjango - それをスライスした後のクエリーセットを並べ替える

qs = Foo.objects.all()[:5] 

、私はいくつかの他の基準(実際には、反対方向に同じ日時フィールドによって)クエリセットを並べ替えたいです。しかし、スライスの後に並び替えることは許されません。 reverse()は最初の注文を元に戻し、私に別のクエリセットを与えます。クエリーセットからリストを作成せずにそれを使って注文することなく、自分が望むものを達成する方法はありますか?

答えて

10

いいえ、それを行う方法はありません。 order_byはデータベース上での操作ですが、クエリーセットをスライスすると評価され、それ以降はデータベースに戻りません。

あなたはすでに解決策を知っているようですが、評価されたqsにreversed()を実行してください。

qs = reversed(Foo.objects.all()[:5]) 
+0

私は何も見逃していません。ありがとう。 – shanyu

+0

私は同じ問題を抱えてダニエルの提案に従いましたが、クエリーセットでcountメソッドを使用できないことがわかりました – thchand

+0

Pythonのドキュメントでreverse()への参照が見つかりません。 –

13

order_byはSQLのデータベース内での順序付けを行います。あなたはすでにそれを使っていて、それをスライスしています。その時点で、結果はメモリに取り込まれます。順序を変更したい場合は、ORMのデータベース内ソートではなく、Pythonのメモリ内ソートを使用する必要があります。

あなたのケースでは、ダニエルはすでに最適なソリューションを与えている:あなたは、単に同じフィールドでソートするために、他のために、ちょうどあなたが持っているリストリバース:あなたが持っていた場合は

qs = Foo.objects.all()[:5] 
objs = reversed(qs) 

をその後、カスタムキー機能をソート()関数を使用したい、他のいくつかのフィールドでソートしたい:

qs = Foo.objects.all()[:5] 
objs = sorted(qs, key=lambda o: o.some_other_field) 
+0

はい、order_byはDB注文です。しかし、スライス後のreverse()(クエリーセットメソッド)が動作していて、クエリを再実行して予期しない結果が出るのは面白いことです。 – shanyu

+0

クエリーセットから結果を取り出すとき、それは依然として有効なクエリーセットです。それを変更した場合(たとえば、reverse()を追加した場合)、再評価されます。 –

1

後期の答えが、これは私だけのために働い:

import random 
sorted(queryset[:10], key=lambda x: random.random()) 
関連する問題