'User' object has no attribute 'notifications'

Viewed 292

Can anyone explain why I got this error: 'User' object has no attribute 'notifications'

I have new model Notification and write in file context_processors.py next one:

def notifications(request):
    if request.user.is_authenticated:
        count = request.user.notifications.filter(is_viewed=False).count()
        return {
            'notifications_count': count
        }
    else:
        return dict()

def notify(request):
    if request.user.is_authenticated:
        notifications = Notification.objects.all()
        return {
            'notifications': notifications
        }
    else:
        return dict()

My model Notification in the same app that is a User and my models looks like this:

class User(AbstractUser):
    class Roles(models.IntegerChoices):
        ......


class Notification(models.Model):
    user = models.ForeignKey('User', models.CASCADE)
    message = models.TextField('Message', max_length=250, default=None)
    is_viewed = models.BooleanField('Seen', default=False)
    created_at = models.DateTimeField(auto_now_add=True, null=True)

    def __str__(self):
        return f"{self.message}"

    class Meta:
        verbose_name = 'MSG'
        verbose_name_plural = 'MSG'
        ordering = ['-created_at',]

Please help me to unserstand what is the problem with User object in context_processors.py

2 Answers

you dont have related_name and default related_name is notification_set.

Add related_name:

user = models.ForeignKey('User', models.CASCADE, related_name"notifications")

Or change queryset

count = request.user.notification_set.filter(is_viewed=False).count()

Since you did not specify a related_name=… [Django-doc] for the ForeignKey from Notification to User, the default name is modelname_set, so in this case notification_set.

You thus can access the notifications with:

count = request.user.notification_set.filter(is_viewed=False).count()

Or you can set the related_name=… to:

class Notification(models.Model):
    user = models.ForeignKey(
        'User',
        models.CASCADE,
        related_name='notifications'
    )

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Related