2020-11-29

How to use dispatch_uid to avoid duplication Signals correctly

Helloo,

I am trying to apply using a dispatch_uid="my_unique_identifier" in order to avoid duplicate signals sent in my project.

I have searched for several similar answers and read the following documentation but I am not sure what I am missing:

https://docs.djangoproject.com/en/3.1/topics/signals/#preventing-duplicate-signals

In my project there are posts that are written by Author, each post has a like button which when clicked by a user notification is created and sent to the author.

Until here everything is fine except that 2 notifications are sent instead of 1. I have tried the following but it did not have any effect and I am still receiving 2 notifications

So here it is:

Here is the Like model.py

class Like(models.Model):
    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)

    def user_liked_post(sender, instance, *args, **kwargs):
        like = instance
        if like.value=='Like':
            post = like.post
            sender = like.user
            dispatch_uid = "my_unique_identifier"
            notify = Notification(post=post, sender=sender, user=post.author, notification_type=1)
            notify.save()

post_save.connect(Like.user_liked_post, sender=Like, dispatch_uid="my_unique_identifier")

Here is the notifications model

class Notification(models.Model):
    NOTIFICATION_TYPES=((1,'Like'),(2,'Comment'),(3,'Admin'))

    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)

    def __str__(self):
        return str(self.post)

Here is the views.py:

def LikeView(request):
    post = get_object_or_404(Post, id=request.POST.get('id'))
    liked = False
    current_likes = post.num_likes
    user = request.user
    if post.author.id == request.user.id:
        messages.warning(request, 'You can not like you own Post')
    else:
        if post.likes.filter(id=request.user.id).exists():
            post.likes.remove(request.user)
            liked = False
            current_likes = current_likes - 1
        else:
            post.likes.add(request.user)
            liked = True
            current_likes = current_likes + 1
        post.num_likes = current_likes
        post.save()

        like, created = Like.objects.get_or_create(user=user, post=post)
        sender = like.user

        if not created:
            if like.value == 'Like':
                like.value = 'Unlike'
                like.delete_notification(sender, post)
            else:
                like.value = 'Like'
        like.save()

    context = {
        'total_likes': post.total_likes,
        'liked': liked,
        'post': post,
    }
    if request.is_ajax:
        html = render_to_string('blog/like_section.html', context, request=request)
        return JsonResponse({'form': html})

Update: Here is what I have tried to replace get_or_create: but got AttributeError: 'Like' object has no attribute 'exists'

    try:
        like = Like.objects.get(user=user, post=post)
        sender = like.user

        if like.exists():
            like.delete()
            like.delete_notification(sender,post)  

        else:
            like = Like(user=user, post=post)
            like.save()
    except Like.DoesNotExist:
        like = Like(user=user, post=post)

        if like.value == 'Like':
            like.value = 'Unlike'
            like.delete_notification(sender, post)
        else:
            like.value = 'Like'
        like.save()

My question is how to use dispatch_uid="my_unique_identifier" correctly inorder to avoid duplicated signals?



from Recent Questions - Stack Overflow https://ift.tt/3mkdtBB
https://ift.tt/eA8V8J

No comments:

Post a Comment