Оглавление
Добрый день, гики!!!
Сигналы в django - это способ для ваших моделей общаться друг с другом при наступлении события. Те, кто работал с JavaScript, скорее всего, сталкивались с методом .addEventListener(), который вызывается только при наступлении события. Этот метод работает так же, как и сигналы django, но на этот раз он вызывается, когда одна часть двух связанных моделей сохраняется, удаляется, обновляется и т.д.
Ниже перечислены некоторые из доступных событий, которые могут быть вызваны.
- pre_save и post_save: Эти события вызываются перед сохранением модели и после сохранения модели соответственно.
- pre_delete и post_delete: Эти события вызываются до или после удаления модели соответственно.
- m2m_changed: Вызывается при изменении поля "многие ко многим" в модели.
- request_started и request_finished: Вызываются до и после того, как HTTP-запрос будет отправлен или завершен соответственно.
Создание рабочего сигнала
Одна очень важная часть моего django приложения, где я использую сигналы, это когда я работаю с моделью, которая имеет отношения один к одному с моделью пользователя. В этом учебнике я буду использовать модель Profile. У каждого пользователя должен быть профиль, который является расширением модели пользователя. На самом деле это можно сделать разными способами, один из которых - переопределить метод сохранения модели пользователя и затем создать профиль для созданного пользователя. Но давайте предположим, что мы хотим, чтобы все было просто и аккуратно, сигналы будут правильным способом.
Я буду считать, что вы уже знаете, как начать проект django, поэтому я пропущу эту часть. Перейдите в файл models.py вашего приложения и создайте модель Profile.
from django.contrib.auth import get_user_model
import uuid
# user object
User = get_user_model()
class Profile(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(User, on_delete=models.CASCADE)
friends = models.ManyToManyField("self", blank=True)
picture = models.ImageField(upload_to="dps")
def __str__(self):
return self.user.username
Хорошо! Мы настроили нашу модель профиля, давайте сделаем миграции и мигрируем в базу данных
$ python manage.py makemigrations
$ python manage.py migrate
Теперь мы хотим, чтобы профили автоматически создавались при создании экземпляра пользователя. Для этого создайте файл в каталоге вашего приложения и назовите его signals.py
#signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Profile, User
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
print(f"Profile for {instance.username} created successfully!!")
Здесь я использовал сигнал post_save, потому что наш профиль будет создан после успешного создания пользователя.
Нам нужно сообщить нашему приложению об этом файле, поэтому перейдите к вашему файлу apps.py, который был создан, когда вы выполнили $ python manage.py startapp , и добавьте в него этот фрагмент кода.
class AccountConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name="account"
# add this
def ready(self):
from . import signals
Теперь все готово. Чтобы это работало, убедитесь, что ваше приложение зарегистрировано в INSTALLED_APPS как <имяприложения>.apps.<имяприложения>Config.
Теперь вы можете создавать экземпляры профилей просто на лету. Спасибо, что прочитали, оставляйте комментарии ниже. До встречи в следующем выпуске.