【发布时间】:2020-07-12 07:30:18
【问题描述】:
我有以下结构,其中从通用模型子类化的内容模块通过“页面模块”模型附加到页面,该模型通过GenericForeignKey 引用它们:
class SitePage(models.Model):
title = models.CharField()
# [etc..]
class PageModule(models.Model):
page = models.ForeignKey(SitePage, db_index=True, on_delete=models.CASCADE)
module_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
module_id = models.PositiveIntegerField()
module_object = GenericForeignKey("module_type", "module_id")
class CommonModule(models.Model):
published_time = models.DateTimeField()
class SingleImage(CommonModule):
title = models.CharField()
# [etc..]
class Article(CommonModule):
title = models.CharField()
# [etc..]
目前,由此填充页面会导致大量 SQL 查询。我想以最高效的数据库方式获取给定页面的所有模块内容(即所有 SingleImage 和 Article 实例)。
我不能直接使用prefetch_related,因为它“必须限制在一组同类结果中”,而且我要获取多种内容类型。
我可以单独获取每个模块类型:
image_modules = PageModule.objects.filter(page=whatever_page, module_type=ContentType.objects.get_for_model(SingleImage)).prefetch_related('module_object_')
article_modules = PageModule.objects.filter(page=whatever_page, module_type=ContentType.objects.get_for_model(Article)).prefetch_related('module_object')
all_modules = image_modules | article_modules
但我需要对它们进行排序:
all_modules.order_by('module_object__published_time')
我不能因为:
“字段‘module_object’不生成自动反向关系 因此不能用于反向查询”
...我不认为我可以将推荐的 GenericRelation 字段添加到所有内容模型中,因为那里已经有内容了。
那么……我可以这样做吗?还是我被卡住了?
【问题讨论】:
-
检查我的问题并回答here我不确定这是否能解决您的订购问题,但至少您可以最大限度地减少所需的查询数量。
-
嗨 - 谢谢,这很有用。我跟着它到了this article,这是我基于它的解决方案;它使 SQL 查询的数量减半。不幸的是,由于它们现在已被
WHERE IN()取代,因此这些查询的效率并不是特别高,但至少是一种改进。
标签: django django-models