我为我的Django项目构建了一个非常基本的私人消息传递模块。
我有一个Message模型,其中包含:
sender (Foreign key to the member model)
recipient (Foreign key to the member model)
message
date (Datetime of which the message was created)
现在我的问题是我想创建一个新视图,它会根据这些消息返回一个对话列表。
我正在尝试编写一个返回最新消息的查询,但在sender = current user或recipient = current user的情况下是唯一的。这是为了让我有一个最新消息列表,它应该相当于一个对话列表。我有没有正确的,或者我完全在想什么?
conversations = Message.objects.filter(Q(recipient=request.user) |
Q(sender=request.user)).annotate(max=Max('date'))
但是这会返回重复的对话我从另一个堆栈溢出帖子中尝试了这个:
conversations = Message.objects.order_by('recipient', 'sender',
'date').distinct('recipient', 'sender')
但是我收到此错误“此数据库后端不支持DISTINCT ON字段”
非常感谢任何帮助。
答案 0 :(得分:3)
正如@Grimmy在评论中所述,请发布更多信息。具体来说,请在您的答案中添加您尝试过的查询(评论中已有的查询)和结果,以及结果有什么问题(您说“重复的说话;您是说每次对话只显示两次或更多比两次?)
对于这种情况,我们会想到两个选项:
Conversation
的新模型,其中包含有关对话的信息,包括成员,开始日期等,并为每条消息添加一个外键,为其分配一个对话(多对一来自消息对话)。这样可以简化您的查询,并且可以轻松扩展以适应“群聊”(如果需要)(只需在对话中添加更多成员),或者对话本身的图片或标题等内容。当您发布更多信息时,如果您愿意,我会更详细地讨论第一选项。现在,我只是说如果你得到重复的对话,其中每个对话只显示两次(一次是用户是发件人,一次是用户是收件人),那么听起来你的查询就足够了你可以在python中编写一个for循环,通过生成的对话进行排序并删除旧的重复项。只要每个用户不超过一两次对话,听起来就像这样,那就不应该太慢地降低性能。
但无论如何,我建议选项二。我必须在Django项目中实现类似的功能,我选择了2.它大大简化了你的查询,如下所示:
# get the conversations the user is in
conversation_list = Message.objects.filter(conversation__participants=user).order_by('-date')
# get a list of the most recent message of each conversation
message_list = conversation_list.values('conversation').annotate(
first_msg=Max('conversation__message')
)
为了使第二行正确对消息进行排序,请将以下内容添加到消息模型中:
class Message(models.Model):
# sender field is unchanged
# date field is unchanged (maybe rename to avoid name collisions with date module)
# message field is unchanged (maybe rename to 'content' to avoid confusion)
# make recipient many-to-many because I'd recommend having both the sender and the recipient listed as recipients,
# but you don't have to do that
recipient = models.ManyToManyField(User)
# conversation foreign key
conversation = models.ForeignKey(Conversation, blank=False, null=False)
# this simplifies sorting so the "Max('conversation__message')" line
# sorts on date rather than primary key
ordering = ["-date"]
以下是对话模型:
class Conversation(models.Model):
participants = models.ManyToManyField(User)
# example functionality you may wish to add later
group_name = models.CharField(max_length=512, default="Group", blank=False, null=False)
profile_picture = models.FileField(upload_to='uploads/', default='uploads/GroupChatIcon.jpg')