6

I found two ways of implementing a symmetrical friendship system (you are my friend, so I am also your friend) in Django:

As suggested inside the docs:

class UserProfile(models.Model):
    friends = models.ManyToManyField(User, related_name='friends')

Now, I'd like to get all "friendly" user AND userprofile models with one select_related-query like so (that should be a reverse joined lookup):

profiles = UserProfile.objects.filter(user__in=request.user.get_profile().friends.all()).select_related()

I query the userprofile, because that way, I can use select_related() and all related objects are cached.

On the other hand, I can define my model referencing the friends field to "self", like so:

class UserProfile(models.Model):
    friends = models.ManyToManyField('self')

Now, my select_related friend lookup looks like that:

profiles = this_user.get_profile().friends.all().select_related()

I always need both, the user object and it's related profile: The second approach is much simpler concerning the reversed lookup via select_related(), but does practically the same. However, by using "self" as field reference, Django handles for me the symmetrical friendship. Thus, I don't have to create two entries per friendship in the database manually. Django does that for me. The symmetrical option, however, does only work on "self" referencing fields.

Which is the better solution? I can't find anything about it. Any ideas appreciated - thanks!

Simon Steinberger
  • 6,605
  • 5
  • 55
  • 97

1 Answers1

3

Simon,

Sometimes its better to use an existing plugin, rather than trying to re-invent the wheel.

Have you had a look at django-friends?

ApPeL
  • 4,801
  • 9
  • 47
  • 84
  • 2
    Hmm, yepp, I know it, thanks; also django-simple-friends ([link](https://github.com/muhuk/django-simple-friends)), however it's not that much work to implement this feature and I rather know exactly what's going on. Both packages are quite extensive in features and documentation on how to use them is very thin. Also both apps create extra models - in favor of simplicity, I rather use **one** many-to-many field and let Django handle the rest. – Simon Steinberger Oct 25 '11 at 13:56