这是简化的问题,我有一个 Book 模型:
class Book(models.Model):
language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES)
...
我正在使用django-hitcount来计算我的 Books 的视图(可能没有人知道它,因为它是一个旧项目),无论如何让我粗略地总结一下:它创建一个 HitCount 对象,其中包含一个命中计数器和一个对应对象的 GenericForeignKey。
我想获得 15 种具有更多点击量的某种语言的书籍,显然是按点击量排序的。
我已经看过这个问题,它帮助我找出了我的(部分)解决方案,分为 3 个查询:
- 获取某种语言的所有图书ID;
- 获取同样在第一个列表中的前 15 个 HitCounts related_object 的 ID;
- 获取步骤 2 中获取的 ID 的书籍;
翻译成代码:
content_type = ContentType.objects.get_for_model(Book)
books = tuple(Books.objects.filter(
language=language).values_list('id', flat=True))
all_time = list(HitCount.objects.filter(
content_type=content_type,
object_pk__in=books).values_list(
'object_pk', 'hits').order_by('-hits')[:15])
all_time_ids = [i[0] for i in all_time]
best_of_all_time = Books.objects.select_related(
'manga').filter(pk__in=all_time_ids)
这种方法存在两个问题:
- 对于大型数据库(如我的),第二个查询变得非常昂贵;
- 在最后一个查询中,我通过第二个查询的命中而丢失了订单;
有人有建议吗?