使用select_related获取related_name对象

时间:2015-10-19 22:11:00

标签: django django-models django-orm

我一直在寻找解决问题的方法,但我似乎无法解决这个问题。

所以我有两个模特:

class Messages(models.Model):
    _db = 'somedb'
    id = models.IntegerField(primary_key=True)
    text = models.TextField()

class MessageTags(models.Model):
    _db = 'somedb'
    id = models.IntegerField(primary_key=True)
    text = models.TextField()
    tag = models.ForeignKey(Tag)
    message = models.ForeignKey(Messages, related_name='tags')

我可以使用以下调用查询给定消息的标记: test = Messages.get(id=234124).tags.all() ^返回MessageTags列表

我想要做的是理论上执行左连接,在那里我获得具有相关MessageTags对象的特定条件的所有消息。我被指向使用select_related的方向,但我无法使用任何东西。

如何获取消息列表,将MessageTags作为每个属性作为.tags(或其他任何内容......)

谢谢!

1 个答案:

答案 0 :(得分:2)

我不相信select_related能够在您正在寻找的方法中执行。但实际上,左派也不会加入。

这样想:一条消息可以有5个标签。如果你进行了连接,你的结果集中将得到5行用于那条消息,这使得它看起来像5条消息。

现在,正如您所指出的,您可以在单个邮件上引用.tags.all()并获取与该邮件关联的所有MessageTag。如果我理解你的情况,这实际上就是你要找的。

当然,如果您尝试优化执行的查询数量,我建议您查看prefetch_related。以下是如何使用它的示例:

messages = Messages.objects.filter(text__icontains='foobar').prefetch_related('tags')
for message in messages:
    for tag in message.tags.all():
        print('Message id', message.id, '- tag', tag.text)

那应该执行2个查询:

  1. 检索已过滤的已过滤消息
  2. 检索与这些消息相关的所有标记