如何对related_name 字段进行查询?

ver*_*4ka 5 django django-models django-orm

我必须通过外键连接模型

class User(AbstractUser):
   ...
Run Code Online (Sandbox Code Playgroud)

class PrivateMessage(models.Model):
    user_from = models.ForeignKey(
        User,
        verbose_name=u'From',
        related_name='sent_messages',
    )
    user_to = models.ForeignKey(
        User,
        verbose_name=u'To',
        related_name='received_messages',
    )
Run Code Online (Sandbox Code Playgroud)

有没有办法获取特定用户的所有地址。例如,如果

u = User.objects.get(id=1)
messages = PrivateMessage.objects.filter(user_from=u)
for m in messages:
    users.add(m.user_to)
Run Code Online (Sandbox Code Playgroud)

如何user_to仅使用 Django ORM 方法获取出现在这些消息中的用户列表?

mar*_*dev 5

ManyToManyField我认为更好的想法是在模型上定义User

class User(AbstractUser):
    #...
    receivers = models.ManyToManyField('self', through='Message',
                                      symmetrical=False, related_name="senders")

class Message(models.Model):
    user_from = models.ForeignKey(MyUser, related_name='messages_from')
    user_to = models.ForeignKey(MyUser, related_name='messages_to')
    message = models.CharField(max_length=100, default="")
    #...
Run Code Online (Sandbox Code Playgroud)

然后要检索另一端的用户列表,您只需执行以下操作:

User.objects.get(id=1).receivers.all()  # who I sent the message to
User.objects.get(id=1).senders.all()    # who sent me a message
Run Code Online (Sandbox Code Playgroud)

这样你就拥有了一个清晰的 API。


ver*_*4ka 1

最后,我写了三个查询:

    users_from = set(PrivateMessage.objects.filter(
        user_to=self.request.user,
    ).values_list(
        'user_from__pk',
        flat=True,
    ))
    users_to = set(PrivateMessage.objects.filter(
        user_from=self.request.user,
    ).values_list(
        'user_to__pk',
        flat=True,
    ))
    interlocutors = User.objects.filter(pk__in=users_from.union(users_to))
Run Code Online (Sandbox Code Playgroud)