python - Django - 私有(private)消息对话 View

标签 python django

我为我的 Django 项目构建了一个非常基本的私有(private)消息传递模块。

我有一个消息模型,其中包含:

sender (Foreign key to the member model)
recipient (Foreign key to the member model)
message
date (Datetime of which the message was created)

现在我的问题是我想创建一个新 View ,它返回基于这些消息的对话列表。

我正在尝试编写一个返回最新消息但唯一的查询,其中发件人=当前用户或收件人=当前用户。这样我就有了最新消息的列表,它应该相当于对话列表。我说得对吗还是我完全想太多了?

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 字段”

任何帮助将不胜感激。

最佳答案

正如@Grimmy 在评论中所述,请发布更多信息。具体来说,请在您的答案中添加您尝试过的查询(您在评论中已经有了)和结果,以及结果有什么问题(您说“重复对话;您的意思是每个对话只出现两次或更多)超过两倍?)

对于这种情况,我想到了两种选择:

  1. 您可以对现有模型运行查询来删除/排除重复项。
  2. 您可以创建一个名为 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')

关于python - Django - 私有(private)消息对话 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43696074/

相关文章:

python - OSV 方法的返回语句

django-rest-auth : email verification failed, 给出错误

python - DRF 使用序列化器验证正文并序列化响应

mysql - 在 GAE 应用中更改 Cloud SQL block_encryption_mode

python - 使用 StreamBlock 时如何解决 Wagtail 循环 block 依赖

python - 为什么发送连续的 UDP 消息会导致消息延迟到达?

python - 如何获取嵌套字符串列表中最长字符串的长度?

javascript - Django /HTML : Send information through a button click?

python - 如何从Python代码库中注释/删除所有打印语句?

python - 如何找到字符串中前导序列的长度?