【问题标题】:How to make an union of prefetch_related from different foreign keys?如何将不同外键的 prefetch_related 联合起来?
【发布时间】: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


【解决方案1】:

我目前正在玩Prefetch。在我看来,它的状态非常好,而且非常强大。

我对您的问题的处理可能是这样的:

entities = Entity.objects.all().prefetch(Prefetch(
    'entity_photo__set',
    EntityPhoto.objects.filter(
        Q(entity=obj) | Q(association__buddy1=obj) | Q(association__buddy2=obj
    )
    to_attr="photos_prefetched",
))

然后您可以使用for entity in entities: entity.photos_prefetched 访问这些照片。

如果这不起作用,则问题可能是您将 (Q(entity=obj)) 引用回实际实体。不确定这是否可行。我在引用回对象时遇到问题,可能是 Django 中的一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 2013-10-06
    • 2018-07-22
    • 1970-01-01
    • 2018-09-16
    • 2021-11-01
    相关资源
    最近更新 更多