Django-クエリ結果の制限


回答:


304

Djangoクエリセットは遅延しています。つまり、特に結果を要求した場合にのみ、クエリがデータベースにヒットします。

したがって、クエリの結果を出力または実際に使用するまで、データベースにアクセスせずにさらにフィルタリングできます。

以下に示すように、コードは1つのSQLクエリのみを実行して、最後の10項目のみをフェッチします。

In [19]: import logging                                 
In [20]: l = logging.getLogger('django.db.backends')    
In [21]: l.setLevel(logging.DEBUG)                      
In [22]: l.addHandler(logging.StreamHandler())      
In [23]: User.objects.all().order_by('-id')[:10]          
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]

私はmongoDBでこれを試しましたが、SELECTはサポートされていませんと言っています。mongoDBでこれを行う方法?
winux 2019年

@winuxこれはDjango固有のものであるため、特にMongo / NoSQLタイプのデータベースで動作するようにDjangoを設定する必要があるかもしれません。これは、標準のDjango ORMセットアップに関して、私の経験では典型的なセットアップではありません。
匿名の臆病者

38

実際、私はこれLIMIT 10がデータベースに発行されるので、スライスはPythonではなくデータベースで発生すると思います。

詳細については、limiting-querysetsを参照してください。


スライス後にはフィルタリングできないため、これもフィルタリングが必要なクエリセットでは機能しないことに注意してください。
Mike 'Pomax' Kamermans '11 / 09/23

2
そのため、スライスするよりも先にフィルタリングします。リンクをありがとうDavor!
Vyachez

13

質問の解決策はDjango 1.7では機能せず、エラーが発生します:「スライスが取得された後はクエリを並べ替えることができません」

ドキュメントによると、https: //docs.djangoproject.com/en/dev/topics/db/queries/#limited-querysets Pythonスライス構文の「step」パラメータを強制すると、クエリが評価されます。それはこのように機能します:

Model.objects.all().order_by('-id')[:10:1]

それでも、制限がSQLまたはPythonで実行されるのか、返された結果配列全体がスライスされるのかと思います。巨大なリストをアプリケーションメモリに取得するのはよくありません。


このソリューションでさえ、テスト済みのdjango> = 1.8では機能しません。
sonus21 2017年

3

はい。オブジェクトの限られたサブセットをフェッチする場合は、以下のコードを使用できます。

例:

obj=emp.objects.all()[0:10]

先頭の0はオプションなので、

obj=emp.objects.all()[:10]

上記のコードは、最初の10個のインスタンスを返します。


1

他の有用な回答への追加と観察として、[:10]スライスとして実際に行うと、最後の10ではなく、リストの最初の10要素が返されることに注意する価値があり ます...

最後の10を取得するには、[-10:]代わりに行う必要があります(ここを参照)。これはorder_by('-id')-を使用して要素を逆にするのを避けるのに役立ちます。


1
これを試してみたところ、「負のインデックス作成はサポートされていません。」
bparker

@DarkCygnus Product.objects.filter(~Q(price=0))[-5:]でも同じエラーが発生します:「負のインデックス作成はサポートされていません。」
bersam

これはdjangoのクエリセットでは機能しません:code.djangoproject.com/ticket/13089クエリセットをリストに変換すると機能します。
バレム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.