Написание сигнала Django для регистрации действий пользователя в модели
Вот мои модели в файле models.py.
class User(AbstractUser):
date_of_birth = models.DateField(blank=True, null=True)
bio = models.TextField(blank=True, null=True)
job = models.CharField(max_length=250, blank=True, null=True)
photo = models.ImageField(upload_to='account_images/',blank=True, null=True)
phone = models.CharField(max_length=11, blank=True, null=True)
followings = models.ManyToManyField('self', through='Contact', related_name='followers', symmetrical=False)
def get_absolute_url(self):
return reverse('social:user_detail', args=[self.username])
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_posts')
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
tags = TaggableManager(blank=True)
likes = models.ManyToManyField(User, related_name='liked_post', blank=True)
saved_by = models.ManyToManyField(User, related_name='saved_post', blank=True)
total_likes = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['-created']
indexes = [
models.Index(fields=['-created'])
]
def __str__(self):
return self.author.username
def get_absolute_url(self):
return reverse('social:post_detail', args=[self.id])
class UserActivity(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_activity')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='post_activity', blank=True, null=True)
action = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user} {self.action} {self.post.author}' post"
Я хочу написать сигнал, в котором, когда пользователю нравится пост, создается объект модели UserActivity, а значение поля user устанавливается на пользователя, которому он понравился. Поле post должно быть установлено в значение поста, который понравился пользователю. А поле action должно быть установлено в 'likes'.
@receiver(post_save, sender=Post.likes.through)
def create_like_activity(sender, instance, **kwargs):
if instance.likes.exists():
UserActivity.objects.create(
user=instance.likes.last(),
post=instance.author,
action='likes'
)
Я пытался добиться этого с помощью данного подхода, но у меня ничего не вышло. Я относительно новичок в этом деле и все еще нахожусь на уровне новичка во многих концепциях. Буду признателен за ваши рекомендации.
Вы слушаете неправильный сигнал.
Вместо этого вы должны слушать сигнал m2m_changed.
Осторожно, этот сигнал подается/отправляется несколько раз
"pre_add" Отправляется до добавления одного или нескольких объектов в отношение.
"post_add" Отправляется после добавления одного или нескольких объектов в отношение.
"pre_remove" Отправляется перед удалением одного или нескольких объектов из
.отношения. "post_remove" Отправляется после удаления одного или нескольких объектов
из отношения. "pre_clear" Отправляется перед очисткой отношения.
"post_clear" Отправляется после очистки отношения.
Вы можете проверить, когда сработает этот сигнал, проверив action
.
Действие:
действие Строка, указывающая тип обновления, которое выполняется для отношения.
Итак, ваш код должен выглядеть следующим образом:
@receiver(m2m_changed, sender=Post.likes.through)
def create_like_activity(sender, instance, action, **kwargs):
if instance.likes.exists() and action == "post_add":
UserActivity.objects.create(
user=instance.likes.last(),
post=instance,
action='likes'
)