使用 select_lated 获取 related_name 对象

pho*_*512 7 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')
Run Code Online (Sandbox Code Playgroud)

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

我想做的是理论上执行左连接,在其中我获取特定条件的所有消息以及关联的 MessageTags 对象。我被指出使用 select_lated 的方向,但我无法让任何东西发挥作用。

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

谢谢你!!

Joe*_*elm 7

我不相信select_related能够以您正在寻找的方法执行。但实际上,左连接也不会。

可以这样想:一条消息可以有 5 个标签。如果执行联接,您将在结果集中获得该一条消息的 5 行,这使得它看起来像 5 条消息。

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

当然,如果您想优化执行的查询数量,我建议您查看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)
Run Code Online (Sandbox Code Playgroud)

这应该执行 2 个查询:

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