25

ここで、Djangoクエリセットは怠惰であり、実際に印刷されるまで評価されないことを読みました。djangoに組み込まれているページ付けを使用して簡単なページ付けを行いました。「django-pagination」や「django-endless」など、その役割を果たしているアプリがすでにあることに気づきませんでした。

とにかく、たとえばこれを行うときに、QuerySetがまだ怠惰であるかどうか疑問に思います

entries = Entry.objects.filter(...)
paginator = Paginator(entries, 10)
output = paginator.page(page)
return HttpResponse(output)

そして、この部分は、現在表示したいページを取得するたびに呼び出されます。

データベースに不必要な負荷をかけたくないので、知る必要があります。

4

2 に答える 2

53

どこで発生しているかを確認したい場合は、インポートdjango.db.connectionして検査してくださいqueries

>>> from django.db import connection
>>> from django.core.paginator import Paginator
>>> queryset = Entry.objects.all()

ページネーターを作成して、クエリが発生するかどうかを確認しましょう。

>>> paginator = Paginator(queryset, 10)
>>> print connection.queries 
[]

まだありません。

>>> page = paginator.page(4)
>>> page
<Page 4 of 788>
>>> print connection.queries 
[{'time': '0.014', 'sql': 'SELECT COUNT(*) FROM `entry`'}]

ページを作成すると、クエリセットに含まれるエントリの数をカウントするためのクエリが1つ生成されます。エントリはまだフェッチされていません。

ページのオブジェクトを変数'objects'に割り当てます。

>>> objects = page.object_list
>>> print connection.queries
[{'time': '0.014', 'sql': 'SELECT COUNT(*) FROM `entry`'}]

これにより、エントリがフェッチされることはありません。

HttpResponseオブジェクトリストからを生成します

>>> response = HttpResponse(page.object_list)
>>> print connection.queries
[{'time': '0.014', 'sql': 'SELECT COUNT(*) FROM `entry`'}, {'time': '0.011', 'sql': 'SELECT `entry`.`id`, <snip> FROM `entry` LIMIT 10 OFFSET 30'}]

最後に、エントリがフェッチされました。

于 2012-05-11T10:07:48.060 に答える
4

です。Djangoのページ付けでは、クエリセットに適用されるのと同じルール/最適化が使用されます。

これは、評価を開始することを意味しますreturn HttpResponse(output)

于 2012-05-11T10:07:26.990 に答える