我正在创建一个私人用户进行用户聊天,为了与某人聊天,联系用户必须在他自己的网址上输入他想与之交谈的用户的用户名。
既然已经建立了这个系统,我想保留聊天记录,以便以后我可以发送聊天通知。要做到这一点,我需要获取每个对话的最后一条消息,并且我想在已连接用户自己的聊天配置文件中显示它。
如下图所示:
模型 renderInput
字段为:userComment
,recipient
,sender
,comment
views.py :
sent_at
models.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')
问题:如何过滤和订购我的观点?
答案 0 :(得分: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
中使用此查询:
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,))
根据模型所在的app
的名称,将appname设置为extra。
现在您可以按如下方式访问它:
for user in users:
print user.username
print user.last_message_time
print user.message
答案 1 :(得分: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})
答案 2 :(得分:0)
[更新]:我刚刚意识到此解决方案仅适用于Postgresql,因为它使用distinct
中的字段名称。
您可以混合使用order_by
和distinct
来获得所需的结果:
过滤用户为client
或worker
的评论:
comments = userComment.objects.filter(Q(client=request.user) | Q(worker=request.user))
使用client
,worker
和sent_at
字段对用户评论进行排序。确保sent_at
字段的降序排序,以便每个客户 - 工作人员对的最新评论位于顶部:
comments = comments.order_by('client', 'worker', '-sent_at')
现在,获取不同的行:
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')
这会为您提供用户为client
或worker
的每个对话的最新评论。