如何正确使用 dispatch_uid 避免重复信号
How to use dispatch_uid to avoid duplication Signals correctly
你好,
我正在尝试使用 dispatch_uid="my_unique_identifier"
进行申请,以避免在我的项目中发送重复信号。
我已经搜索了几个类似的答案并阅读了以下文档,但我不确定我遗漏了什么:
https://docs.djangoproject.com/en/3.1/topics/signals/#preventing-duplicate-signals
在我的项目中,有作者编写的 post,每个 post 都有一个点赞按钮,当用户点击该按钮时,会创建通知并发送给作者。
到这里为止一切都很好,除了发送了 2 个通知而不是 1 个。我尝试了以下但没有任何效果,我仍然收到 2 个通知
这里是:
点赞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")
这是通知模型
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)
这里是 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})
更新:
这是我试图替换的内容 get_or_create:但得到了 AttributeError: 'Like' object has no attribute 'exists'
try:
like = Like.objects.filter(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()
我的问题是如何正确使用 dispatch_uid="my_unique_identifier" 以避免信号重复?
您创建了一个赞并再次保存了它。这就是为什么:
like, created = Like.objects.get_or_create(user=user, post=post)
like.save()
get_or_create
意思如下:
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
因为在你的情况下,每次点击喜欢,它都是一个新对象(我想)?然后,get_or_create
将转到 except
和 save()
。所以你节省了两倍。
以下可能会解决您在评论中提到的like->unlike->like的问题。
替换:
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()
和
try:
like =Like.objects.get(user=user, post=post)
like.delete()
like.delete_notification(sender, post) # this part seems weird, you did not define ```sender``` in this view.
except Like.DoesNotExist:
like = Like(user=user, post=post)
like.save()
你好,
我正在尝试使用 dispatch_uid="my_unique_identifier"
进行申请,以避免在我的项目中发送重复信号。
我已经搜索了几个类似的答案并阅读了以下文档,但我不确定我遗漏了什么:
https://docs.djangoproject.com/en/3.1/topics/signals/#preventing-duplicate-signals
在我的项目中,有作者编写的 post,每个 post 都有一个点赞按钮,当用户点击该按钮时,会创建通知并发送给作者。
到这里为止一切都很好,除了发送了 2 个通知而不是 1 个。我尝试了以下但没有任何效果,我仍然收到 2 个通知
这里是:
点赞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")
这是通知模型
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)
这里是 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})
更新:
这是我试图替换的内容 get_or_create:但得到了 AttributeError: 'Like' object has no attribute 'exists'
try:
like = Like.objects.filter(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()
我的问题是如何正确使用 dispatch_uid="my_unique_identifier" 以避免信号重复?
您创建了一个赞并再次保存了它。这就是为什么:
like, created = Like.objects.get_or_create(user=user, post=post)
like.save()
get_or_create
意思如下:
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
因为在你的情况下,每次点击喜欢,它都是一个新对象(我想)?然后,get_or_create
将转到 except
和 save()
。所以你节省了两倍。
以下可能会解决您在评论中提到的like->unlike->like的问题。
替换:
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()
和
try:
like =Like.objects.get(user=user, post=post)
like.delete()
like.delete_notification(sender, post) # this part seems weird, you did not define ```sender``` in this view.
except Like.DoesNotExist:
like = Like(user=user, post=post)
like.save()