0

We have a notification system in place (model extract below) and every time the site needs to notify any user about anything, it creates a notification. Now we want to show that on every site (we use a global template) a counter of the unread messages without changing every view to deliver it to the template. Is there any way to do this right?

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)

Our query would be Notification.objects.filter(n_recipient=request.user, n_read_status=False).count() but we don't want to call it in every view manually.

creyD
  • 1,972
  • 3
  • 26
  • 55

2 Answers2

1

You can use 2 options:

1 - Using template tags:

Custom template tags and filters

Basically call a custom template tag with user object and get the notification data when you need it.

2 - Using django middleware:

Django docs: Middleware

Add your notification data to request context. Example here:

Django - How to modify template context from middleware

Option one makes more sense cause you might not need notification data everywhere and it requires to check for user objects and ... which can be extra unnecessary process and error handling is kinda harder and if you don't handle it properly, it can cause errors on every page while template tags only used when needed.

Navid Zarepak
  • 4,148
  • 1
  • 12
  • 26
1

Like @DanielRoseman and @Navid2zp pointed out, the correct solution would probably be a template tag which is created by adding a templatetags folder (more info in Django docs). Our working code below:

HTML template

{% 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) + ')'
creyD
  • 1,972
  • 3
  • 26
  • 55