[英]Adding If statement to signals not working properly
每当用户喜欢或评论作者收到有关此活动的通知的帖子时,我都会为我的 Django 项目设置通知系统。
我已经阅读了 django 中的信号: https : //docs.djangoproject.com/en/3.1/topics/signals/#listening-to-signals
在帖子模型中,我添加了一个num_likes
,它反映了帖子收到的点num_likes
数。
我正在尝试添加一个选项,以便当num_likes
达到某个数字时,帖子的作者可以收到通知。 在我的例子中,它是第一个赞。
所以,这是我尝试过的,但什么也没发生。
这是models.py
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)
def __str__(self):
return self.title
#---------------------------My trial------------------------------------------
def like_progress(sender, instance, *args, **kwargs):
post = instance
if post.num_likes == 1:
notify = Notification(post=post, user=post.author, notification_type=3)
notify.save()
# num_likes
post_save.connect(Post.like_progress, sender=Post)
#---------------------------My trial------------------------------------------
这是通知 model.py
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)
text_preview= models.CharField(max_length=90,blank=True)
date=models.DateTimeField(auto_now=True)
is_seen=models.BooleanField(default=False)
def __str__(self):
return self.notification_type
这是通知应用程序 views.py
def ShowNotifications(request, *args, **kwargs):
user=request.user
notifications= Notification.objects.filter(user=user).order_by('-date')
Notification.objects.filter(user=user, is_seen=False).update(is_seen=True)
template= loader.get_template('notifications/notifications.html')
context = {
'notifications': notifications,
}
return HttpResponse(template.render(context, request))
这是 url.py
app_name = 'notifications'
urlpatterns = [
path('', ShowNotifications, name='show-notifications'),
这是模板:
<!-- Admin Notification -->
{% if notification.notification_type == 3 %}
Your First Like in this post
{% endif %}
<!-- Admin Notification -->
所以总结一下:
我有一个完美运行的通知系统,我只是想在其中添加一个选项,以通知帖子的Author
他收到了第一个赞。 我在上面做错了什么,我怎样才能让这个功能工作?
如果有任何模糊或需要更多信息,请询问
由于您的视图中有这两行,您没有收到通知:
notifications= Notification.objects.filter(user=user).order_by('-date')
Notification.objects.filter(user=user, is_seen=False).update(is_seen=True)
让我解释一下这些行中发生了什么。
is_seen
为 True。is_seen=False
通知,因为您已经在步骤 2 is_seen=True
它们更新为is_seen=True
。 因此,呈现通知的模板中的循环没有显示任何内容,因为它在数据库中找不到任何看不见的通知。为了缓解这种情况,请将步骤 1 中的通知转换为列表,以便立即执行查询。 通过这种方式,您将一个实际的对象列表传递给您的模板,而不是一个惰性查询集。
这可以解决您的问题:
notifications= list(Notification.objects.filter(user=user).order_by('-date'))
将其转换为列表会强制 Django 立即执行查询并返回对象
在与.models.Post
相同的目录中而不是在模型中的新文件like_progress
中定义like_progress
。 这将有助于避免副作用。
在实践中,信号处理程序通常定义在与它们相关的应用程序的信号子模块中。
在 appConfig 中为包含Post
模型的应用程序注册信号处理程序,我将应用程序称为“博客”,因此模块路径是blog.apps.BlogConfig
并将该模块路径添加到INSTALLED_APPS
,而不仅仅是应用程序名称。
从文档:
信号接收器在应用程序配置类的 ready() 方法中连接。
并查看有关 ready 方法的更多信息。
博客应用程序(无论Post
模型所在的位置)中的 apps.py 文件应如下所示:
from django.apps import AppConfig
from django.db.models.signals import post_save
class BlogConfig(AppConfig):
name = 'blog'
def ready(self):
from .models import Post
from .signals import like_progress
post_save.connect(like_progress, sender=Post)
请注意,导入需要在ready
方法中进行。 还有一个选项可以将模型导入指定为字符串。
请记住,在创建通知时还要指定另一个用户作为发件人。 如:
notify = Notification(post=post, user=post.author, sender=liker, notification_type=3)
您可能想查看有关避免重复注册信号处理程序的文档。
这一切都在您链接到的文档中,但它有助于了解 shell ( python manage.py shell
) 中发生的情况。 起初它默默地失败了,但是一旦将信号处理程序移入signals.py 并在appConfig 中注册,它就开始显示一些结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.