Лучший способ организовать модели приватного чата django-channels один к одному?

Я хочу смоделировать таблицу базы данных приватного чата django channels наиболее эффективным способом, чтобы извлечение сообщений не занимало много времени. Для этого я создал комнату один к одному, так как у каждых двух пользователей должна быть своя уникальная комната. Но меня беспокоит то, что поскольку отправитель и получатель сообщения может быть только одним из двух пользователей комнаты, я не хочу устанавливать (отправитель и получатель) как внешний ключ к таблице users. Могу ли я предложить лучшую реализацию этого. Или есть ли другой способ моделирования этих таблиц. Любая помощь будет высоко оценена.

Вот models.py файл.

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}"

Дизайн кажется нормальным. Вы можете добавить больше ограничений, чтобы убедиться, что сообщение принадлежит нужным пользователям.

Вот мои предложения:

  1. Сделайте first_user и second_user NOT NULL поля.
  2. Убедитесь, что у вас есть ровно 1 комната для пары пользователей (first_user.id < second_user.id)
  3. Убедитесь, что пара (получатель, отправитель) равна паре (первый_пользователь, второй_пользователь)
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'
            ),
        ]
Вернуться на верх