views:

409

answers:

1

Hay I've got a question about relationships.

I want to Users to have Friendships. So a User can be a friend with another User. I'm assuming i'll need to use the ManyToManyField, through a Friendship table. But i cannot get it to work. Any ideas?

Here are my models.

class User(models.Model):
    username = models.CharField(max_length=999)
    password = models.CharField(max_length=999)
    created_on = models.DateField(auto_now = False, auto_now_add = True)
    updated_on = models.DateField(auto_now = True, auto_now_add = False)
    friends = models.ManyToManyField('self')
    pendingFriends = models.ManyToManyField('self', through='PendingFriendship', symmetrical=False, related_name='friend_requested')

class PendingFriendship(models.Model):
    user = models.ForeignKey('User', related_name='user')
    requested_friend = models.ForeignKey('User', related_name='requested_friend')
    created_on = models.DateField(auto_now = False, auto_now_add = True)
    updated_on = models.DateField(auto_now = True, auto_now_add = False)

Thanks

+1  A: 

Many-to-many field is described in the documentation. Just do:

class User(models.Model):
    username = models.CharField(max_length=999)
    password = models.CharField(max_length=999)
    created_on = models.DateField(auto_now = False, auto_now_add = True)
    updated_on = models.DateField(auto_now = True, auto_now_add = False)
    friends = models.ManyToManyField('self')

You only have to use through if you want to add extra fields to the relation. Another description of all the possibilities is described in this section.

As you name your model User, I assume you are not using the build in authentication framework. But if you use it, you don't have to implement the authentication yourself, so think about it.

Update: Have you read the sections I linked to? There it is described:

There are a few restrictions on the intermediate model:

  • Your intermediate model must contain one - and only one - foreign key to the target model (this would be Person in our example). If you have more than one foreign key, a validation error will be raised.
  • Your intermediate model must contain one - and only one - foreign key to the source model (this would be Group in our example). If you have more than one foreign key, a validation error will be raised.
  • The only exception to this is a model which has a many-to-many relationship to itself, through an intermediary model. In this case, two foreign keys to the same model are permitted, but they will be treated as the two (different) sides of the many-to-many relation.
  • When defining a many-to-many relationship from a model to itself, using an intermediary model, you must use symmetrical=False (see the model field reference).
Felix Kling
I've updated the example, with your amend. However i still need the extra table to hold data.
dotty
@dotty: I updated my answer.
Felix Kling
hmm, ive updated my model, it passes validation fine. Ive added a couple of Users. and created a PendingFriendship object on user A's model. This adds the friendship fine, however user b's object doesnt get the other side of the friendship (im asuming because the 'symmetrical' value is false). I want the relationship to be symmetrical though. any ideas?
dotty