2017-01-07 51 views
4

我正在为用户聊天创建一个私人用户,为了与某人聊天,所连接的用户必须输入用户的用户名,并与他想要在他自己的网址上进行交谈。如何向用户对话显示每个用户的最后一条消息以保存聊天记录?

既然这个系统已经建好了,我想保留一个聊天记录,以便稍后我可以发送聊天通知。为此,我需要获取每个对话的最后一条消息,并且我想在连接的用户自己的聊天档案中显示它。

正如下面的图片:

enter image description here

型号userComment领域是:recipientsendercommentsent_at

views.py

def inbox(request, username): 
    username = User.objects.get(username=username) 
    connected_user = request.user 

    if username == connected_user: 

     #I'm having the issue on this line 
     users = userComment.objects.filter(Q(client=request.user) | Q(worker=request.user)).order_by(?) 

    else: 
     users = userComment.objects.filter(Q(Q(client=request.user) & Q(worker=username)) | Q(Q(client=username) & Q(worker=request.user))).order_by('sent_at') 

models.py

class userComment(models.Model): 
    client = models.ForeignKey(User, related_name="client") 
    worker = models.ForeignKey(User, blank=True, null=True, related_name="worker") 
    sent_at = models.DateTimeField(auto_now_add=True) 
    comment = models.TextField(max_length=255, null=True) 

    def __str__(self): 
     return str(self.client) 

问:如何才能筛选并订购我认为这样做呢?在额外按名称

user = request.user 

users = User.objects.filter(Q(r__sender=user) | Q(s__recipient=user)).distinct().extra(select={'last_message_time': 'select MAX(sent_at) from appname_usercomment where (recipient_id=auth_user.id and sender_id=%s) or (recipient_id=%s and sender_id=auth_user.id)'}, select_params=(user.id, user.id,)).extra(order_by=['-last_message_time']).extra(select={'message': 'select comment from appname_usercomment where (sent_at=(select MAX(sent_at) from appname_usercomment where (recipient_id=auth_user.id and sender_id=%s) or (recipient_id=%s and sender_id=auth_user.id)) and ((recipient_id=auth_user.id and sender_id=%s) or (recipient_id=%s and sender_id=auth_user.id)))',}, select_params=(user.id, user.id,user.id, user.id,)) 

设置应用程序的名字:

回答

1

首先,在您的userComment模型反向关系

class UserComment(models.Model): 
    sender = models.ForeignKey(User, related_name='sender', related_query_name='s') 
    recipient = models.ForeignKey(User, related_name='recipient', related_query_name='r') 
    sent_at = models.DateTimeField(auto_now_add=True) 
    comment = models.TextField() 

现在,在您views.py使用添加相关查询名称此查询其中模型是app

现在,您可以通过以下方式访问它:

for user in users: 
    print user.username 
    print user.last_message_time 
    print user.message 
0
def inbox(request, username)  
    # first select all the comments related to user 
    user = User.objects.get(username=username) 
    related = userComment.objects.filter(q(client=user) | q(worker=user)).order_by('-sent_at') 

    # This selects the latest comments. 
    # Now loop over the related comments and group them. 
    chats = {} 
    for comment in related: 
     if comment.client == user: 
      previous_chat_history = chats.setdefault(comment.worker.username, []) 
      if not len(previous_chat_history) >= 3: 
       previous_chat_history.append(comment) 
     if comment.worker== user: 
      previous_chat_history = chats.setdefault(comment.client.username, []) 
      if not len(previous_chat_history) >= 3: 
       previous_chat_history.append(comment) 

    # Reverse each list to keep the latest message last 
    for k, v in chats.items(): 
     chats[k] = v.reverse() 

    return render(request, 'template.html', context={chats: chats}) 
+0

不行的,这只能得到所有查询的最后一个项目。我希望它得到每个不同的消息集的最后一个项目,再加上如果它是由日期时间排序,然后有一个巨大的问题是,你可以在一个错误的收件箱中收到来自其他用户的消息。 – Lindow

+0

@KasimovNuriddin请张贴UserComment在模型 – eskawl

+0

我已经张贴模型 – Lindow

0

[更新]:我刚刚意识到,因为它是在distinct使用的字段名该解决方案将只可和PostgreSQL合作。


你可以混合order_bydistinct,以达到预期的效果:

  1. 过滤用户所在要么client的评论或worker

    comments = userComment.objects.filter(Q(client=request.user) | Q(worker=request.user)) 
    
  2. 顺序用户评论clientworkersent_at字段。确保有sent_at场从高到低的顺序,从而为每一个客户,员工对最新的评论是在顶部:

    comments = comments.order_by('client', 'worker', '-sent_at') 
    
  3. 现在,得到了不同行:

    comments = comments.distinct('client', 'worker') 
    

    这将只保留第一行是每个客户机 - 工作对的最新评论,并删除查询集中的其余行。


在一个声明:

comments = userComment.objects \ 
       .filter(Q(client=request.user) | Q(worker=request.user)) \ 
       .order_by('client', 'worker', '-sent_at') \ 
       .distinct('client', 'worker') 

这会给你的每个对话中的最新评论,其中用户可以是一个clientworker

相关问题