web-dev-qa-db-ja.com

Django QuerySetで制限とオフセットを指定しても機能しません

Django 1.6.5を使用していて、MySQLのgeneral-query-logをオンにしているので、SQLがMySQLにヒットしていることがわかります。
そして、DjangoのQuerySetでより大きな制限を指定しても機能しないことに気づきました。

_>>> from blog.models import Author  
>>> len(Author.objects.filter(pk__gt=0)[0:999])
>>> len(Author.objects.all()[0:999])
_

そして、MySQLの一般的なログは、両方のクエリに_LIMIT 21_があることを示しました。

ただし、21未満の制限は機能します。 len(Author.objects.all()[0:10])は_LIMIT 10_でSQLを作成します。

何故ですか?設定する必要があるものはありますか?

14
adamsmith

シェルからクエリを実行すると発生します。デバッグ時に端末が数千のレコードでいっぱいになるのを防ぐために、LIMIT句が追加されています。

クエリセットのrepr()を印刷していました(または少なくとも印刷しようとしていました)。誤って100万件の結果を取得して印刷しようとする人を避けるために、最初の20件の結果のみを取得して印刷し、それ以上の場合は「残りの切り捨て」を印刷するように変更しました。これは、クエリを21件の結果に制限することで実現されます(21件の結果がある場合は20件を超えるため、「切り捨てられた」メッセージを出力します)。これはrepr()でのみ発生します-つまり、診断印刷専用です。通常のユーザーコードにはこの制限が自動的に含まれていないため、100万を超える結果を繰り返すクエリセットを作成できます。

ソース

22
akxlr

Djangoは、Pythonの配列スライシング構文を使用してOFFSETを実装します。最初の10個の要素をオフセットしてから、次の5個の要素を表示する場合は、それを使用します

MyModel.objects.all()[OFFSET:OFFSET+LIMIT]

たとえば、10のオフセットの後に5人の作成者をチェックしたい場合、コードは次のようになります。

Author.objects.all()[10:15]

あなたはそれについてもっと読むことができます ここで公式Django doc

12
argo

オフセットと制限のために私は私のために使用し、働いた:)

MyModel.objects.all()[offset:limit]

例えば:-

Post.objects.filter(Post_type=typeId)[1:1]
2
jayant singh

私は動作しますが、Djangoはイテレータを使用します。すべてのオブジェクトを一度にロードするわけではありません。

1
guettli

LIMITOFFSETは、Djangoでは同じようには機能しません。これは、私たちが期待する方法です。

例えば。

10行目から次の10行を読み取る必要があり、次のように指定した場合:

Author.objects.all()[10:10]

空のレコードリストを返します。次の10行をフェッチするには、制限にオフセットを追加する必要があります。

Author.objects.all()[10:10+10]

そして、10行目から始まる次の10行のレコードリストを返します。

1
shakir Baba