如何获取当前用户和其他人之间的最后一条消息?

Posted

技术标签:

【中文标题】如何获取当前用户和其他人之间的最后一条消息?【英文标题】:How to get last message between current user and others? 【发布时间】:2015-12-16 20:50:39 【问题描述】:

我有一个 消息 django-model,带有字段:

id(主键) user_sender(用户实例的外键) user_receiver(用户实例的外键) send_date(日期时间) 消息(字符) 状态(布尔值)

所以,我正在尝试获取当前用户和其他用户之间的所有最新消息。

例子:

如果我有 3 个用户:

约翰向莎拉发送消息(17.08.2015) (id=1)

莎拉向约翰发送消息(20.08.2015) (id=2)

John 向 Max (18.08.2015) (id=3) 发送消息

我只需要获取 ID 为 2 和 3 的消息。

我正在尝试此查询,但收到所有 3 条消息:

Message.objects.filter(
            Q(user_sender_id=1) |
            Q(user_receiver_id=1)).\
order_by('user_sender', 'user_receiver', '-send_date').\
distinct('user_sender', 'user_receiver')

那么,我做错了什么?为什么在使用外键不同后我收到 3 条消息?

UPD #1:

class Message(models.Model):
    """
    Model for user messages.
    - Who
    - Whom
    - When
    - Message
    - Status
    """
    user_sender = models.ForeignKey(User, related_name="sender")
    user_receiver = models.ForeignKey(User, related_name="receiver")
    send_date = models.DateTimeField(auto_now_add=True)
    message = models.CharField(max_length=500)
    status = models.BooleanField(default=False)

    def __unicode__(self):
        return u'%s %s ->%s' % (self.send_date, self.user_sender, self.user_receiver)

【问题讨论】:

请展示您的模型的真实代码 如果您想通过此查询获取消息 2 和 3,那么您正在寻找来自或来自 John 的消息。但是消息 1 也来自 John。 @Pynchia 更新问题。 @Ivan 还有什么?您能提供丢弃重复外键对的解决方案吗? @Ivan 说您的查询不符合您的要求。应该是Message.objects.filter(user_sender_id=1).latest('send_date') 【参考方案1】:

获取当前用户和其他用户之间的所有最新消息:

def is_latest(qs, message):
    # if contact exist in sent and received
    # take lastmessage contact
    if qs:
        if message.send_date < qs[0].send_date:
            return False
    return True

user = User.objects.get(id = 1)
sent = Message.objects.filter(user_sender=user).order_by('user_receiver','-send_date').distinct('user_receiver') 
received = Message.objects.filter(user_receiver=user).order_by('user_sender','-send_date').distinct('user_sender') 
messages = list(chain(sent, received))
contact_list = []
for message in messages:
    if message.user_sender == user:
        c = message.user_receiver                
        if not is_latest(received.filter(user_sender=c), message): continue
    else:
        c = message.user_sender
        if not is_latest(sent.filter(user_receiver=c), message): continue

    contact_list.append('id':c.id,'email': c.email,'last_message': message.message)

print(contact_list)

【讨论】:

【参考方案2】:
sent = Message.objects.filter(user_sender_id=1).order_by('-send_date')[:1]
received = Message.objects.filter(user_receiver_id=1).order_by('-send_date')[:1]

from itertools import chain

messages = list(chain(sent, received))

【讨论】:

看起来不错,但不能完全成功。我正在使用带有消息的数据库对其进行测试,但似乎总是只收到 2 条消息?为什么要抛弃别人? 因为 [:1] 对于每个查询集*只会收到一条消息。如果您希望收到最后五条消息,只需将第二个查询集中的 [:1] 更改为 [:5] 哇!比看起来很棒。标记为答案并睡觉,明天将测试它。谢谢你:) 它看起来不像我需要的那样工作。它选择所有消息,但我只需要当前用户和其他用户之间的一个(最新)。 发送和接收的查询集,带[:1],只会带一条消息,可以显示你的查询集代码吗?

以上是关于如何获取当前用户和其他人之间的最后一条消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 smack 和 openfire 获取 IOS 中每个聊天会话的最后一条消息?

在 SQL 中选择发送者和接收者之间的最后一条消息

如何使用 XMPP ios8 获取最后一个对话用户?

如何将每个用户的最后一条消息显示给用户对话以保留聊天记录?

如何获取所有最新消息,但每条用户消息限制为一条

如何获取特定频道 discordjs 的最后一条消息