Reputation: 882
I am trying to create notification whenever a user likes a post. For that I am using django signals. I have previously used the sender arguement in the receiver decorator but don't why its not working this time. Here are my files.
#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())
The receiver doesn't catch the signal when sender=Post, when I remove the sender it works as intended. On print the positional arguement sender of likeNotification function. This is what I get
<class 'socialuser.models.Post_liked_by'>
What am I doing wrong? Do I need to reference to the intermediate class Post_liked_by, if so how do I do that?
Upvotes: 1
Views: 772
Reputation: 476614
You should specify the through
model of the ManyToManyField
of the model, so Post.liked_by.through
, not Post
: otherwise it is not clear on what ManyToManyField
you are subscribing. We thus define the handler as:
#core/signals.py
@receiver(m2m_changed, sender=Post.liked_by.through)
def likeNotification(sender,**kwargs):
# …
You can boost the efficiency to determine the number of likes with:
#socialuser/models.py
class Post(Authorable, Creatable, Model):
# …
def no_of_likes(self):
return self.liked_by.count()
then it will determine the number of likes at the database side, and thus reduce the bandwidth from the database to the Django/Python application layer.
Upvotes: 2