単一のクエリを好み、を使用している場合は、@Crazyshezyがコメントで提供している優れたリンクMySQL
を確認してください。
バックエンドの場合、可能なクエリは次のとおりです( toとtoからのnull許容でない関係があると仮定):
PostgreSQL
FK
Book
Author
Author
Category
SELECT * FROM (
SELECT book_table.*, row_number() OVER (PARTITION BY category_id ORDER BY RANDOM()) AS rn
FROM book_table INNER JOIN author_table ON book_table.author_id = author_table.id
) AS sq
WHERE rn <= 5
次に、それをaでラップして、インスタンスRawQuerySet
を取得できますBook
from collections import defaultdict
qs = Book.objects.raw("""The above sql suited for your tables...""")
collection = defaultdict(list)
for obj in qs:
collection[obj.category_id].append(obj)
categories_w_rand_books = []
for category in c:
categories_w_rand_books.append((category, collection[category.id]))
キャッシュを使用せずに、リクエストごとにこのクエリを直接実行したくない場合があります。
さらに、コードは最大で50 * 5 = 250Book
秒をランダムに生成しますが、1ページには多すぎるように見えるので、なぜだろうと思います。アイテムはタブなどで表示されていますか?おそらく、Ajaxを実行してSQLの数を減らすか、要件を単純化することができますか?
アップデート
book.author
別のクエリよりもトリガーなしで使用するには、prefetch_related_objects
from django.db.models.query import prefetch_related_objects
qs = list(qs) # have to evaluate at first
prefetch_related_objects(qs, ['author'])
# now instances inside qs already contain cached author instances, and
qs[0].author # will not trigger an extra query
上記のコードは、作成者をバッチでプリフェッチし、それらをに入力しqs
ます。これは別のクエリを追加するだけです。