I have added a notification everytime a user submits a Like button to a post, the owner of the liked post receives a notification.
I have set Value options for each Like button to be Like
or Unlike
so now I am trying to restrict the notification to be sent only if the Value of the like clicked is Like
only.
So, now in the Like Model I have added signal and a condition that if the Like.value== Like
the signal activates but for some reason it is not working and I am not sure why.
My question is:
How do I set the notification signal to be sent only when the Like.value== Like
?
Here is the post models.py:
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
likes = models.ManyToManyField(User, related_name='liked', blank=True)
Here is the like models.py:
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike')
)
class Like(models.Model):
# To know Who liked
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=8)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.post}-{self.user}-{self.value}"
def user_liked_post(sender, instance, *args, **kwargs):
if Like.value=='Like':
like = instance
post = like.post
sender = like.user
notify = Notification(post=post, sender=sender, user=post.author, notification_type=1)
notify.save()
else:
None
def user_unlike_post(sender, instance, *args, **kwargs):
like = instance
post = like.post
sender = like.user
notify = Notification.objects.filter(post=post, sender=sender, user=post.author, notification_type=1)
notify.delete()
# Likes
post_save.connect(Like.user_liked_post, sender=Like)
post_delete.connect(Like.user_unlike_post, sender=Like)
Here is the notifications models.py
class Notification(models.Model):
NOTIFICATION_TYPES=((1,'Like'),(2,'Comment'),(3,'Follow'))
post = models.ForeignKey('blog.Post', on_delete=models.CASCADE, related_name="noti_post", blank=True, null=True)
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="noti_from_user")
user = models.ForeignKey(User, on_delete=models.CASCADE,related_name="noti_to_user")
notification_type= models.IntegerField(choices=NOTIFICATION_TYPES)
Here is the views.py:
def ShowNotifications(request):
user=request.user
notifications= Notification.objects.filter(user=user).order_by('-date')
template= loader.get_template('notifications/notifications.html')
context= {
'notifications':notifications
}
return HttpResponse(template.render(context, request))
Within the post_save handler you compare as following if Like.value=='Like':
But Like
is a class, of which value
is a Field, thus the compare is never True
.
def user_liked_post(sender, instance, *args, **kwargs):
like = instance
if like.value=='Like':
post = like.post
sender = like.user
notify = Notification(
post=post, sender=sender, user=post.author, notification_type=1
)
notify.save()
Another thing that I notice, of what I'm not sure what the impact is. def user_liked_post
is a method on the model. Thus the first argument it expects is self
. But the post save handler is using it as a classmethod. But because of that sender
will probably be cls
, thus Like
.