[英]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.