Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

A better way to orgainize django-channels one to one private chat models?

I want to model the database table of a django channels private chat in the most effective way possible so that retrieving the messages would not take a lot of time.
For that I have create a one to one room since every two users should have their unique room.
And I created a separate message table with a foreign key relation with the (oneToOneRoom) table.But what bothers me is that since the sender and the receiver of the message can only be one of the two users of the room I do not want set (sender and receiver) as foreign Key to the users table. Can I have a better implementation of that. Or is their any other way of modeling those tables. Any help would be highly appreciated.

Here is the models.py file.

class singleOneToOneRoom(models.Model):
    first_user = models.ForeignKey(
        User, on_delete=models.SET_NULL, related_name="first_user", blank=True, null=True)
    second_user = models.ForeignKey(
        User, on_delete=models.SET_NULL, related_name="second_user", blank=True, null=True)
    room_name = models.CharField(max_length=200, blank=True, unique=True)

    def __str__(self):
        return f"{self.first_user}-{self.second_user}-room"

    class Meta:
        unique_together = ["first_user", "second_user"]


class messages(models.Model):
    room = models.ForeignKey(
        singleOneToOneRoom, on_delete=models.CASCADE, related_name="messages")
    message_body = models.TextField()
    sender = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="msg_sender")
    receiver = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="msg_receiver")
    date_sent = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.sender}_to_{self.receiver}"

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The design seems ok. You can add more constraints to be sure, that message belongs to the right users.

Here my suggestions:

  1. Make first_user and second_user NOT NULL fields.
  2. Make sure, that you have exactly 1 room for users pair (first_user.id < second_user.id)
  3. Make sure, that (receiver, sender) pair equals (first_user, second_user) pair
class singleOneToOneRoom(models.Model):
    first_user = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="first_user", null=False)
    second_user = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="second_user", null=False)


    class Meta:
        unique_together = ["first_user", "second_user"]
        constraints = [
            models.CheckConstraint(check=Q(first_user__id__lt=F('second_user__id')), name='unique_user_pair'),
        ]


class messages(models.Model):
    room = models.ForeignKey(
        singleOneToOneRoom, on_delete=models.CASCADE, related_name="messages")
    message_body = models.TextField()
    sender = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="msg_sender")
    receiver = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="msg_receiver")


    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(sender=F('singleonetooneroom__first_user') & Q(receiver=F('singleonetooneroom__second_user'))
                    | Q(sender=F('singleonetooneroom__second_user') & Q(receiver=F('singleonetooneroom__first_user')), 
                name='valid_sender_and_receiver'
            ),
        ]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading