Django Функция приемника сигналов не принимает отправителя
Я пытаюсь создать уведомление каждый раз, когда пользователю нравится сообщение. Для этого я использую django signals. Я уже использовал аргумент отправителя в декораторе получателя, но не знаю, почему он не работает в этот раз. Вот мои файлы
#core.signals.py
@receiver(m2m_changed, sender=Post)
def likeNotification(sender,**kwargs):
if kwargs['action'] == "post_add" and not kwargs['reverse']:
post = kwargs['instance']
to_user = post.user
liked_by_users = kwargs['pk_set']
like_notification = [Notification(
post=post,
user=to_user, sender=User.objects.get(id=user),
text=f"{User.objects.get(id=user).profile.username} liked your post.", noti_type=3
) for user in liked_by_users]
Notification.objects.bulk_create(like_notification)
#socialuser.models.py
class Post(Authorable, Creatable, Model):
caption = TextField(max_length=350, null=True, blank=True)
liked_by = ManyToManyField(
"core.User", related_name="like_post", blank=True)
objects = PostManager()
def no_of_likes(self):
return len(self.liked_by.all())
Приемник не ловит сигнал, когда sender=Post, когда я удаляю отправителя, он работает как положено. При печати позиционного аргумента sender функции likeNotification. Вот что я получаю
<class 'socialuser.models.Post_liked_by'>
Что я делаю неправильно? Нужно ли мне ссылаться на промежуточный класс Post_liked_by, если да, то как это сделать?
Вы должны указать through модель ManyToManyField модели, поэтому Post.liked_by.through, а не Post: иначе неясно, на какую ManyToManyField вы подписываетесь. Таким образом, мы определяем обработчик следующим образом:
#core/signals.py
@receiver(m2m_changed, sender=Post.liked_by.through)
def likeNotification(sender,**kwargs):
# …
Повысить эффективность определения количества лайков можно с помощью:
#socialuser/models.py
class Post(Authorable, Creatable, Model):
# …
def no_of_likes(self):
return self.liked_by.count()
то он будет определять количество лайков на стороне базы данных, и таким образом уменьшит пропускную способность от базы данных до уровня приложения Django/Python.