如果您更喜欢单个查询并且正在使用MySQL
,请查看@Crazyshezy 在他的评论中提供的出色链接。
对于后端,可能的查询是(假设从to和 from toPostgreSQL
有不可为空的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
然后,您可以将其包装在 aRawQuerySet
中以获取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
秒,我只是想知道为什么,因为单页看起来太多了。项目是否显示为选项卡或其他内容?也许您可以通过执行 Ajax 来减少 SQL 的数量,或者简化需求?
更新
要使用book.author
w/o 触发多于另一个查询,请尝试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
. 这只是添加了另一个查询。