views:

180

answers:

2

I'm trying to accomplish something akin to twitter on my website, where one user can follow another one. I want to select all User records that are following a User with a given ID. My follow relationship model look like:

class Following(models.Model):
  user = models.ForeignKey(User, related_name='is_following')
  followed = models.ForeignKey(User, related_name='is_followed')

And I'm using the django.contrib.auth.models User class.

Assuming I have a User object named "myUser" representing the followed person, what's the appropriate query to get everyone following them?

A: 

That's where the related_name attribute comes into play -- it allows you to follow a relationship backwards. So, to get all the users following a particular user, you'd use my_user.is_followed.

Obviously you might want to rename your attributes to reflect these relationships, since followed and is_followed might be a bit confusing, but that's how you'd do it.

mipadi
Hmm, when I try that, it returns (when printed in the template):<django.db.models.fields.related.RelatedManager object at 0x153c290>All I'm doing is following = user.is_prospect_of. Am I missing something? I'm very new to Django.
Aaron
That object is a QuerySet, so you need to call one of the QuerySet methods (`all()`, `filter()`, etc.) to work with the objects. If you're printing in a template, you probably want to call `all` in a `for` tag.
mipadi
+3  A: 

mipadi's answer is missing '.all'.

In a view, the queryset

followers = my_user.is_followed.all()

returns a list of Following objects where my_user is being followed. To get the user that is following from a Following object f, use f.user

If followers is in the template context, you could do the following.

{% for f in followers %}

  {{ f.user }}

{% endfor %}

You might find the Django documentation for many to many relationships useful.

Alasdair
Thanks Alasdair. So that returns a list of Following objects. I need the User objects on the other side of the relationship.
Aaron
I think I've fixed it now. following/follower/is_following... my head hurts!
Alasdair
Thanks! So now I'm just looping through the resulting query set and isolating the users. Is that hitting the database once for each user? Or does the initial db call return the user objects as part of the result?
Aaron
I'm not sure. You could have a look at the `django.core.context_processors.debug` context processor. It allows you to display a list of the SQL queries when in debug mode. http://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-debug
Alasdair
You might want to explore select_related() as well. Optimising SQL queries isn't really my area of expertise, so I'll leave you to it. Good luck! http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4
Alasdair