我有一个
TextMessage
模型,如您所见:
class TextMessaage(models.Model):
id = models.UUIDField(
_("Id"),
primary_key=True,
default=uuid.uuid4,
editable=False,
null=False,
blank=False,
)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
modified_at = models.DateTimeField(_("Modified at"), auto_now=True)
sender = models.ForeignKey(
User,
on_delete=models.PROTECT,
related_name="sent_messages",
blank=False,
null=False,
verbose_name=_("Sender"),
)
receiver = models.ForeignKey(
User,
on_delete=models.PROTECT,
related_name="received_messages",
blank=False,
null=False,
verbose_name=_("Receiver"),
)
body = models.TextField(
null=False,
blank=False,
validators=[MaxLengthValidator(4096)],
verbose_name=_("Body"),
)
我想做的是获取用户参与的每个对话的最后一条消息。我试过这个:
conversations = (
models.TextMessage.objects.filter(Q(sender=user) | Q(receiver=user))
.order_by(
"sender__id",
"receiver_id",
"-modified_at",
)
.distinct("sender__id", "receiver_id")
).all()
问题是我编写的查询将考虑与 (sender=B,receiver=A) 不同的对 (sender=A,receiver=B),这不是我正在寻找的。我希望这两对假设相同,因为无论它们的顺序如何,它们都共享相同的外键。简而言之,我只想要用户参与的每个对话中的最后一条消息,以便我可以显示为列表(如 Whatsapp 聊天列表)。我该怎么办?
为了添加更多信息,我顺便使用 Postgres。
您可以像这样使用@property(模型属性)来实现这些事情
class TextMessaage(models.Model):
id = models.UUIDField(
_("Id"),
primary_key=True,
default=uuid.uuid4,
editable=False,
null=False,
blank=False,
)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
modified_at = models.DateTimeField(_("Modified at"), auto_now=True)
sender = models.ForeignKey(
User,
on_delete=models.PROTECT,
related_name="sent_messages",
blank=False,
null=False,
verbose_name=_("Sender"),
)
receiver = models.ForeignKey(
User,
on_delete=models.PROTECT,
related_name="received_messages",
blank=False,
null=False,
verbose_name=_("Receiver"),
)
body = models.TextField(
null=False,
blank=False,
validators=[MaxLengthValidator(4096)],
verbose_name=_("Body"),
)
@property
def last_msg(self):
last_m = TextMessaage.objects.filter(receiver=self.receiver).order_by('-created_at').first()
return last_m
all_msg = TextMessaage.objects.all() # get all conversations
for m in all_msg:
print(m.sender.username)
print(m.receiver.username)
print(m.body)
print(m.created_at)
print(m.last_m) # This will print the last message sent to the user
print("************")