Question

I am making a very minimal user-to-user messaging app using Django 1.4. I want to fetch unread messages that a user received in a straightforward way from my templates. My model looks something like this:

from django.contrib.auth.models import User

class Message(models.Model):
    sender = models.ForeignKey(User, related_name='messages_sent')
    receiver = models.ForeignKey(User, related_name='messages_received')
    read = models.BooleanField(default=False)

Now I can easily access the messages that a user has received from user.messages_received. I'd like to filter this queryset, though, to quickly access the unread messages in an easy way. I know that I can always filter the queryset user.messages_received.filter(read=False), but I'd like to get at them directly in templates, possibly like this:

<a href="{% url inbox %}"> Inbox ({{ user.unread_messages.count }})</a>

I suspect I want to make a Manager, but I'm not sure how to write it or where to attach it.

Thanks in advance.

Was it helpful?

Solution

There are two ways to accomplish this that come to my mind.

First, you could extend the user model with a custom function.

from django.contrib.auth.models import User

def unread_messages(self):
    return self.messages_received.filter(read=False)
User.add_to_class('unread_messages', unread_messages)

But that is slightly hacky. The "clean" way would be not to extend the User model directly, but to create a UserProfile for your users and add the function there. The docs describe this quite well.

In your case:

models.py

from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    def unread_messages(self):
        return self.user.messages_received.filter(read=False)

settings.py

AUTH_PROFILE_MODULE = 'appname.UserProfile'

template

{{ user.get_profile.unread_messages.count }}

The code is untested, but should work :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top