#python #django
#python #django
Вопрос:
У меня проблема с удалением уведомлений, которые были ранее отправлены, когда пользователю понравился пост.
Сначала у меня есть кнопка «Мне нравится», связанная с сообщением, которое работает нормально.
Моя проблема в том, что у меня есть модель Post и подобная модель (отношение «многие ко многим»), и я создал модель signal from notification, в которой, когда пользователь нажимает «Нравится» на сообщение, отправляется сигнал и создается уведомление, но я борюсь с логикой, согласно которой, если тот же пользователь Unlike
публикует сообщение(нажав кнопку «Мне нравится» во второй раз), я хочу, чтобы был отправлен сигнал для удаления созданного уведомления от того же пользователя.
Итак, в настоящее время происходит вот что:
- Пользователь нажимает кнопку «Мне нравится». Значение кнопки Like равно
Like
- Уведомление отправлено автору сообщения
- Тот же пользователь снова нажимает кнопку «Мне нравится». Значение кнопки Like равно
Unike
- Ничего не происходит
Требуемый результат:
- Ранее отправленное автору уведомление о том, что сообщение понравилось, будет удалено
Я хочу, чтобы ранее отправленное уведомление было удалено, когда сообщение не было отправлено
Вот мой Models.py связано с моделью Post:
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author')
num_likes = models.IntegerField(default=0, verbose_name='No. of Likes')
likes = models.ManyToManyField(User, related_name='liked', blank=True)
Вот views.py:
class PostDetailView(DetailView):
model = Post
template_name = "blog/post_detail.html"
def get_context_data(self, *args, **kwargs):
context = super(PostDetailView, self).get_context_data()
post = get_object_or_404(Post, slug=self.kwargs['slug'])
total_likes = post.total_likes()
liked = False
if post.likes.filter(id=self.request.user.id).exists():
liked = True
post_likes = post.likes.all()
context["liked"] = liked
context["post_likes"] = post_likes
return context
Как Models.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
notify = Notification(post=post, sender=sender, user=post.author, notification_type=1)
notify.save()
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()
post_save.connect(Like.user_liked_post, sender=Like)
post_delete.connect(Like.user_unlike_post, sender=Like)
Вот как 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:
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.user_unliked_post(sender=sender, post=post) <------- My trial
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})
Я попытался добавить user_unlike_post
, LikeView
но получаю сообщение об ошибке AttributeError: 'Like' object has no attribute 'user_unliked_post'
Я не уверен, правильно ли было пытаться удалить предыдущий сигнал из LikeView
.
Мой вопрос, как я могу удалить предыдущее уведомление, отправленное, когда пользователь в отличие от post?
Ответ №1:
Вы можете создать функцию delete_notification
, подобную следующей.
def delete_notification(sender, post):
notify = Notification.objects.filter(post=post, sender=sender, user=post.author, notification_type=1)
notify.delete()
И вызовите функцию LikeView
.
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:
like, created = Like.objects.get_or_create(user=user, post=post)
sender = like.user
if not created:
if like.value == 'Like':
like.value = 'Unlike'
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})
Надеюсь, это сработает.
Также обратите внимание, что оба метода user_liked_post
and user_unlike_post
являются отсутствующими self
аргументами в вашей Like
модели.
Комментарии:
1. Я добавил функцию delete_notification и вызвал ее в view.py но я получаю ошибку типа: delete_notification() принимает 2 позиционных аргумента, но было задано 3
2. Как 3 аргумента передаются функции delete_notification? Вы добавили новые аргументы при вызове? Где вы помещаете функцию delete_notification в свой код?
3. после условия if
like.delete_notification(sender, post)
4. Затем сделайте подпись к этому
def delete_notification(self, sender, post):
Добавьтеself
аргумент.