你可以利用两个
JOIN
在这里,比如:
Chat.objects.filter(
participants__sender=user_a,
participants__receiver=user_b
).filter(
participants__sender=user_b,
participants__receiver=user_a
)
这将导致如下查询:
SELECT chat.id, chat.created
FROM chat
INNER JOIN participant ON chat.id = participant.chat_id
INNER JOIN participant T5 ON chat.id = T5.chat_id
WHERE participant.receiver_id = user_b AND participant.sender_id = user_a
AND T5.receiver_id = user_a AND T5.sender_id = user_b
因此它将返回所有
Chat
两个这样的对象
Participant
对象存在。
不过,上述情况并不理想,因为我们做了两个
加入
s、 如果有
unique_together
对参与者的约束,如:
class Participant(models.Model):
chat = models.ForeignKey(Chat, on_delete=models.CASCADE, related_name='participants')
sender = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
receiver = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
class Meta:
unique_together = ['sender', 'receiver']
我们可以数一数
参与者
对象,例如:
from django.db.models import Count, Q
Chat.objects.filter(
Q(participants__sender=user_a, participants__receiver=user_b) |
Q(participants__sender=user_b, participants__receiver=user_a)
).annotate(
nparticipants=Count('participants')
).get(
nparticipants=2
)
这将使用以下查询:
SELECT chat.id, chat.created, COUNT(participant.id) AS nparticipants
FROM chat
INNER JOIN participant ON chat.id = participant.chat_id
WHERE (participant.receiver_id = user_b AND participant.sender_id = user_a)
OR (participant.receiver_id = user_a AND participant.sender_id = user_b)
GROUP BY chat.id
HAVING COUNT(participant.id) = 2
我们可以利用
.get(..)
这里,因为
独一无二
约束,保证最多有一个
聊天
对象,该对象将存在。这样我们就可以用
Chat.DoesNotExist
例外。
不过,我并不真的相信以上的模型是理想的。首先记录的数量将按比例增加
二次型
参加人数:三人有六项记录。此外
聊天
从概念上讲可能不是“定向的”:没有发送方和接收方,有两个或更多的对等方共享信息。