Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

8.4 Создание моделей чата
1 из 1 шага пройден

Перед тем, как приступить к созданию моделей нашего чата, давайте установим следующие зависимости:

pip install channels
pip install daphne


Daphne — это сервер протоколов HTTP, HTTP2 и WebSocket для ASGI и ASGI-HTTP, разработанный для поддержки каналов Django.

INSTALLED_APPS = [
    'channels',
    'daphne'
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts',
    'chat'
]


Также нам необходимо добавить ASGI_APPLICATION для нашего приложения, для этого рядом с WSGI_APPLICATION добавим следующую строку:

WSGI_APPLICATION = 'django_channels_chat.wsgi.application'
ASGI_APPLICATION = 'django_channels_chat.asgi.application' # new


Теперь мы можем запустить наш сервер. Поскольку мы добавили channels и daphne в список INSTALLED_APP, он возьмет на себя обработку команды runserver и запустит сервер ASGI, а не сервер WSGI:

 

Модели чата

Для нашего приложения нам понадобятся три модели баз данных: GroupMessage и Event.

  • Модель Group будет хранить всю информацию о групповом чате, такую как название группы и ее участников.
  • Модель Message будет хранить информацию о сообщениях, которые были отправлены в группе. Информация будет включать отправителя сообщения, группу, которой оно было отправлено, отметку времени сообщения и содержание сообщения.
  • Модель Event будет хранить информацию о пользователе, присоединяющемся к группе или покидающем ее, а также временную метку, когда он вступил или вышел.


Чтобы создать модели, откройте models.py файл и добавьте следующие классы моделей:

from django.db import models
from django.contrib.auth import get_user_model
from uuid import uuid4

from django.urls import reverse

User = get_user_model()


class Group(models.Model):
    ''' Групповая модель, в которой несколько пользователей могут делиться идеями и обсуждать их '''
    uuid = models.UUIDField(default=uuid4, editable=False)
    name = models.CharField(max_length=30)
    members = models.ManyToManyField(User)

    def __str__(self) -> str:
        return f"Group {self.name}-{self.uuid}"

    def get_absolute_url(self):
        return reverse("group", args=[str(self.uuid)])

    def add_user_to_group(self, user: User):
        '''Вспомогательная функция для добавления пользователя в группу и создания объекта'''
        self.members.add(user)
        self.event_set.create(type="Join", user=user)
        self.save()

    def remove_user_from_group(self, user: User):
        '''Функция для удаления членов группы, когда они выходят из группы чата'''
        self.members.remove(user)
        self.event_set.create(type="Left", user=user)
        self.save()

Мы даем группе UUID, имя, а затем список участников, который в данном случае представлен объединением «многие-ко-многим» с существующей кастомной моделью User, которую мы реализовали в прошлом разделе.

Также мы добавили пару вспомогательных функций, с помощью которых у нас появилась возможность добавлять и удалять пользователя из группы.

 

Модель сообщения

Модель сообщения будет довольно простая и понятная:

class Message(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    content = models.TextField()
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    def __str__(self) -> str:
        date = self.timestamp.date()
        time = self.timestamp.time()
        return f"{self.author}:- {self.content} @{date} {time.hour}:{time.minute}"

 

Модель события

Мы будем отслеживать приходящих и уходящих пользователей с помощью данной модели событий.

Модель, которая хранит все события, связанные с группой, например, когда пользователь присоединяется к группе или покидает ее:

class Event(models.Model):
    CHOICES = [
        ("Join", "join"),
        ("Left", "left")
        ]
    type = models.CharField(choices=CHOICES, max_length=10)
    description= models.CharField(help_text="A description of the event that occurred",\
    max_length=50, editable=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    group = models.ForeignKey(Group ,on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        self.description = f"{self.user} {self.type} the {self.group.name} group"
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return f"{self.description}"

 

Миграции

Следующим шагом будет запуск миграции для только что созданных вами моделей:

python manage.py makemigrations chat
python manage.py migrate


Мы видим что наши таблицы успешно создались:


Включите три модели в файл admin.py, чтобы иметь к ним доступ на странице администратора:

from .models import *

# Register your models here.

admin.site.register(Message)
admin.site.register(Event)
admin.site.register(Group)

 


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Илья, вот вам как опытному программисту, сколько времени понадобилось, чтобы весь материл данного и предыдущего курсов знать, что называется, на зубок. Я вот прошел предыдущий курс 3 раза, но хоть убейте, есть много чего, что до сих пор не могу по памяти написать/пересказать. Вообще как часто программисты, особенно начинающие, заглядывают в справочники или открывают старые проекты, чтобы кое-что подсмотреть? 

@Агаси_Мироян, Специально ничего не учил, такие знания нарабатываются за несколько лет практики. Любые программисты постоянно обращаются к документации, и к своим старым проектам, обычное дело использовать наработки из них в новых проектах. Всё запомнить невозможно, да и начинает забываться, если долго не пишешь. Лучше всего запоминается та информация, которую пришлось самостоятельно найти и применить при реализации конкретной задачи.

@Илья_Перминов, спасибо за такой развернутый ответ, прям гора с плеч. 

опять же тут такая же ситуация где это создавать не понятно у нас не одно приложение!

 

Модели чата

Для нашего приложения нам понадобятся три модели баз данных: GroupMessage и Event.

  • Модель Group будет хранить всю информацию о групповом чате, такую как название группы и ее участников.
  • Модель Message будет хранить информацию о сообщениях, которые были отправлены в группе. Информация будет включать отправителя сообщения, группу, которой оно было отправлено, отметку времени сообщения и содержание сообщения.
  • Модель Event будет хранить информацию о пользователе, присоединяющемся к группе или покидающем ее, а также временную метку, когда он вступил или вышел.


Чтобы создать модели, откройте models.py файл и добавьте следующие классы моделей:

from django.db import models
from django.contrib.auth import get_user_model
from uuid import uuid4

from django.urls import reverse

User = get_user_model()


class Group(models.Model):
    ''' Групповая модель, в которой несколько пользователей могут делиться идеями и обсуждать их '''
    uuid = models.UUIDField(default=uuid4, editable=False)
    name = models.CharField(max_length=30)
    members = models.ManyToManyField(User)

    def __str__(self) -> str:
        return f"Group {self.name}-{self.uuid}"

    def get_absolute_url(self):
        return reverse("group", args=[str(self.uuid)])

    def add_user_to_group(self, user: User):
        '''Вспомогательная функция для добавления пользователя в группу и создания объекта'''
        self.members.add(user)
        self.event_set.create(type="Join", user=user)
        self.save()

    def remove_user_from_group(self, user: User):
        '''Функция для удаления членов группы, когда они выходят из группы чата'''
        self.members.remove(user)
        self.event_set.create(type="Left", user=user)
        self.save()

@No_Name, в этом разделе рассматривается создание моделей чата, соответственно все модели будут добавляться в файл models.py приложения chat.

в модели события в методе Event.save(), в super().save(*args, **kwargs)  пропущены ** 

@Константин_Дмитров, спасибо, исправил.