python - 如何正确使用 dispatch_uid 避免重复信号
问题描述
你好,
我正在尝试使用 a 来应用dispatch_uid="my_unique_identifier"
,以避免在我的项目中发送重复的信号。
我搜索了几个类似的答案并阅读了以下文档,但我不确定我缺少什么:
https://docs.djangoproject.com/en/3.1/topics/signals/#preventing-duplicate-signals
在我的项目中,有作者撰写的帖子,每个帖子都有一个点赞按钮,当用户点击该按钮时,通知会创建并发送给作者。
直到这里一切都很好,除了发送 2 个通知而不是 1 个。我尝试了以下但没有任何效果,我仍然收到 2 个通知
所以这里是:
这是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")
这是通知模型
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()
推荐阅读
- python - 列表理解更改列表元素
- flutter - 获取要在子级中使用的父级大小
- localization - 如何在 ICU MessageFormat 中表示俄语或其他复杂复数语言的复数规则
- javascript - TypeError:无法读取未定义的属性“名称”。我找不到出现此错误的原因。我正在使用 mysql、nodejs 和 ejs 作为视图引擎
- c++ - 我可以将向量作为 initial_sum 和不同的函数传递给 std::accumulate 吗?
- android - 如何使用recaptcha v3?
- azure - Azure AD B2C - 只有通过自定义策略才能在首次登录场景中重置密码?
- javascript - 在从 firebase 获取值之前执行图表
- r - 在 observeEvent 中更新输入并更改 ui
- reactjs - 如何在 React 中只请求一次 API 数据,而不是每次访问时都呈现页面?