我们已经有了一个通知系统(下面的模型摘录),每当站点需要将任何事情通知任何用户时,它都会创建一个通知。现在,我们希望显示在每个站点(我们使用全局模板)上未读消息的计数器,而无需更改每个视图以将其传递到模板。有没有办法做到这一点?
class Notification(models.Model):
n_id = models.AutoField(primary_key=True)
n_body = models.CharField(max_length=1000, null=True)
n_recipient = models.ForeignKey(User, related_name='Recipient', on_delete=models.CASCADE)
n_read_status = models.BooleanField(default=False)
我们的查询为Notification.objects.filter(n_recipient=request.user, n_read_status=False).count()
,但我们不想在每个视图中手动调用它。
答案 0 :(得分:1)
您可以使用2个选项:
1-使用模板标签:
Custom template tags and filters
基本上使用用户对象调用自定义模板标签,并在需要时获取通知数据。
2-使用django中间件:
将通知数据添加到请求上下文。此处的示例:
Django - How to modify template context from middleware
第一种方法更有意义,因为您可能不需要到处都需要通知数据,并且它需要检查用户对象,并且...这可能是多余的过程,并且错误处理还比较困难,如果您处理不当,模板标记仅在需要时使用,它会在每个页面上导致错误。
答案 1 :(得分:1)
就像@DanielRoseman和@ Navid2zp指出的那样,正确的解决方案可能是通过添加templatetags
文件夹(more info in Django docs)创建的模板标签。我们的工作代码如下:
HTML模板
{% load notifications %}
{{ messages|getmessages:request.user }}
notifications.py
from django import template
from Toolbox.models import Notification
from django.contrib.auth.models import User
register = template.Library()
@register.filter
def getmessages(value, user):
number = Notification.objects.filter(n_recipient=user, n_read_status=False).count()
return '' if number == 0 else ' (' + str(number) + ')'