【发布时间】:2017-07-20 10:30:33
【问题描述】:
我有三个模型,我们举个假想的例子:
class Entity(models.Model):
name = models.CharField()
class EntityAssociation(models.Model):
buddy1 = models.ForeignKey(Entity, related_name='+')
buddy2 = models.ForeignKey(Entity, related_name='+')
class EntityPhoto(models.Model):
entity = models.ForeignKey(Entity, null=True)
association = models.ForeignKey(EntityAssociation, null=True)
title = ...
我们有一些人 (Entity) 可以分享自己的个人照片。我们也有一些实体之间的关系(由EntityAssociation 表示),它们也可以一起分享它们的照片。
对于单个实体,我可以直接或通过关联检索与实体关联的所有照片,这样做:
obj = Entity.objects.last()
EntityPhoto.objects.filter(
Q(entity=obj) | Q(association__buddy1=obj) | Q(association__buddy2=obj)
)
我想要的是能够预取一组选定实体的所有照片。一个典型的用例是:
for entity in Entity.objects.all().prefetch(???):
print(entity.name, 'has', len(entity.photos_prefetched), 'photos')
print([x.title for x in entity.photos_prefetched])
这应该返回所有照片。具有三个查询的解决方案(实体列表,通过entity 预取,通过association attr 预取;两个将是完美的)会满足我,但更重要的是能够遍历单个列表,在每个实体上
我试图查看Prefetch 的内部代码,但看起来预取与查找相关联,而且我不知道在这种情况下如何进行 Q 查询(@ 中的正确操作数应该是什么? 987654329@?)
注意:这里的重点不是重构数据库结构(EntityAssociation 用于许多其他事情,因此它不能简化为 EntityPhoto 的 M2M .) 但如果可能的话,优化这个特定的用例。
【问题讨论】:
-
您最终找到了一个好的解决方案吗?
-
@konoufo 不。我仍在进行两次单独的预取以获取实体的所有照片。然而,我的用例演变了,所以我不再需要单个合并列表,所以我没有进一步挖掘:-)
标签: django optimization django-orm