如何获取当前用户和其他人之间的最后一条消息?
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],只会带一条消息,可以显示你的查询集代码吗?以上是关于如何获取当前用户和其他人之间的最后一条消息?的主要内容,如果未能解决你的问题,请参考以下文章