Лучший способ организовать модели приватного чата 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}"
Дизайн кажется нормальным. Вы можете добавить больше ограничений, чтобы убедиться, что сообщение принадлежит нужным пользователям.
Вот мои предложения:
- Сделайте
first_userиsecond_userNOT NULLполя. - Убедитесь, что у вас есть ровно 1 комната для пары пользователей (first_user.id < second_user.id)
- Убедитесь, что пара (получатель, отправитель) равна паре (первый_пользователь, второй_пользователь)
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'
),
]