Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django many-to-many recursive relationship

Tags:

python

django

I want to implement a basic social network model in django, i.e., followers and followees

class CustomUser(User):
    followers = models.ManyToManyField('self', related_name='followees',
                                       related_query_name='followee')

and above is what I define.I think this will be enough because the manytomany field provide backtrack query. Do I still need to create a followees ManyToMany filed?

And could anybody help write the function how to get the number of followers and followees, as well as followers list and followees list. I'm new to django So I'm confused about the many-to-many field

like image 602
Ziqi Liu Avatar asked Sep 17 '17 19:09

Ziqi Liu


2 Answers

@olieidel is right, but here is one more REALLY important thing, you shouldn't miss in your example: normally, M2M-relations are symmetrical. It means, that if you set User A as follower of User B, querysets will also return User B as follower of User A.

You can avoid such behavior by adding symmetrical=False option to the field:

followers = models.ManyToManyField(
    to='self', 
    related_name='followees', 
    symmetrical=False
)
like image 160
Igor Pomaranskiy Avatar answered Nov 17 '22 06:11

Igor Pomaranskiy


  1. No, you don't have to create a (second) followees ManyToMany field. This is already taken care of by specifying related_name='followees'. On a sidenote, there's no need to specify related_query_name as its value is set to the value of related_name by default.

  2. A ManyToManyField returns a RelatedManager which allows you to do some queries on it similar to a QuerySet. In your case you're interested in the count():

    custom_user = CustomUser().save()
    
    # add followers etc..
    
    followers_count = custom_user.followers.count()
    followees_count = custom_user.followees.count()
    

The Django Docs have some nice examples for ManyToMany Relationships.

like image 7
olieidel Avatar answered Nov 17 '22 07:11

olieidel