Skip to content Skip to sidebar Skip to footer

Django - Private Messaging Conversation View

I have built a very basic private messaging module for my Django project. I have a Message model which consists of: sender (Foreign key to the member model) recipient (Foreign key

Solution 1:

As @Grimmy stated in the comments, please post more information. Specifically, please add to your answer the query you tried (which you already have in the comments) and the result, and what is wrong with the result (you say "duplicate converstations; do you mean each conversation shows up just twice, or more than twice?)

Two options come to mind for this situation:

  1. You could run a query on your existing model that removes/excludes duplicates.
  2. You could create a new model called Conversation which holds information about the conversation, including members, date started, etc., and add a foreign key to each message assigning it one conversation (many-to-one from message to conversation). This would simplify your queries and would be easily extendable to accommodate "group chats" if need be (just add more members to the conversation), or things like a picture or title for the conversation itself.

When you post more information, I'll address option one in more detail if you would like. For now, I'll just say that if you are getting duplicate conversations where each conversation only shows up twice (once where the user is the sender and once where the user is the recipient), then it sounds like your query is good enough and you can just write a for loop in python that sorts through the resulting conversations and removes the older duplicates. As long as each user is in no more than over one or two hundred conversations, which sounds like the case, that shouldn't slow down performance too much.

But in any event, I recommend option two. I had to implement a similar feature in a Django project, and I went with option 2. It greatly simplifies your query to look like this:

# 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')
)

In order for that second line to sort messages properly, add the following to your Message model:

class Message(models.Model):
    # sender field is unchanged
    # date field is unchanged (maybe rename to avoid name collisions withdatemodule)
    # 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 ondate rather than primary key
    ordering = ["-date"]

Here is the Conversation model:

class Conversation(models.Model):
    participants = models.ManyToManyField(User)

    # example functionality you may wish toadd 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')

Post a Comment for "Django - Private Messaging Conversation View"