次のように定義されたメソッドがあります。
def get_featured_books(cats=0):
"""
This method would return a list of featured books
"""
fbooks = list()
categories = models.Category.objects.annotate( bookcount=Count('book')).order_by('bookcount')[:cats].reverse()
for item in categories:
fbooks.append(item.book_set.latest('posted_date'))
return fbooks
ホームページ ビューで上記の方法を使用して、おすすめの書籍のリストを表示します。テンプレートでは、次のタグを使用します。
{% for book in featured %}
<h2>{{ book.title }}({{ book.category}})</h2>
<span class="authors">{{book.authors.all|join:','}}</span>
{% endfor %}
しかし、この全体の概念は多くのクエリを作成します。たとえば、おすすめの本を 10 冊表示したい場合は、次のようにします。
categories = models.Category.objects.annotate( bookcount=Count('book')).order_by('bookcount')[:cats].reverse()
1 つのクエリを作成します。
for item in categories:
fbooks.append(item.book_set.latest('posted_date'))
10個のクエリを作成します。
テンプレート{{ book.category}}
で{{ book.authors.all }}
は、書籍ごとに 1 つのクエリが作成されるため、私のシナリオでは、上記の 2 つのタグで 20 件のクエリが作成されます。これにより、合計 30 個のクエリになります (10 個のレコードのリストを表示するだけです)。もちろん、追加のクエリを作成するホームページに表示する他のものがあります。
問題は、どうすればより少ない(最小限の)いいえにすることができるかです。上記の情報を取得するクエリの。いつもの練習は何ですか?
(PS: キャッシュについては知っており、情報をキャッシュできることも知っていますが、ここでの目的は効率的なクエリの作成について学ぶことです。)
アップデート:
KrzysiekSzularzが提案したように、次のようにandを使用してみましたが、django デバッグ ツールバーはまだ 32 個のクエリを作成していることを示しています。select_related
prefetch_related
def get_featured_books(cats=0):
"""
This method would return a list of featured books
"""
fbooks = list()
categories = models.Category.objects.select_related().annotate( bookcount=Count('book')).order_by('bookcount')[:cats].reverse()
for item in categories:
fbooks.append(item.book_set.prefetch_related('category').latest('posted_date'))
return fbooks