67

I'm coming from a Rails background, and am having a bit of trouble making use of the "Association Methods" provided in Django. I have two models (which have been simplified for the sake of brevity), like so:

class User(models.Model):
    username = models.CharField(max_length=100, unique=True)
    companies = models.ManyToManyField('Company', blank=True)

class Company(models.Model):
    name = models.CharField(max_length=255)

According to the Django documentation:

"It doesn't matter which model has the ManyToManyField, but you should only put it in one of the models -- not both.".

So I understand that if I have an instance of a User, called user, I can do:

user.companies

My question is how do I do the reverse? How do I get all users that belong to a Company instance, let's say Company:

company.users # This doesn't work!

What's the convention to do this? The documentation that I've read doesn't really cover this. I need the association to work both ways, so I can't simply move it from one model to the other.

Mike Trpcic
  • 25,305
  • 8
  • 78
  • 114

1 Answers1

122
company.user_set.all()

will return a QuerySet of User objects that belong to a particular company. By default you use modelname_set to reverse the relationship, but you can override this be providing a related_name as a parameter when defining the model, i.e.

class User(models.Model):
    companies = models.ManyToManyField(Company, ..., related_name="users")

> company.users.all()

here is the relevant documentation

tbm
  • 1,142
  • 12
  • 22
Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • 19
    +1 for related_name. Always *hated* the 'model_set' syntax. It's so dirty feeling. – Josh Brown Mar 03 '14 at 19:35
  • 1
    I think it feels _lazy_ to me. It's not hard to infer an appropriate backwards relation based on class names. The related_name makes it much easier to work with though. – Mike Trpcic Dec 10 '14 at 02:50
  • It still gives me object has no attribute error in a similar scenario – 277roshan Nov 03 '15 at 07:10
  • 4
    Why companies = models.ManyToManyField(User, ..., related_name="users") and not companies = models.ManyToManyField(Company, ..., related_name="users") ? – Nico Zimmer Mar 27 '19 at 11:12
  • @Nico Zimmer It specifies the remote side of the relation (which has the class Company). The local side is implicit (class User here, because that's where the definition is placed within). The "funny thing" is that you specify how the field in the Company class should be called inside the User class. Note that this "related_name" thing is not just for cosmetic use only; one model might have several different relation to one other model (like, Company has one relation "super_users", another one "blocked_users" and a third one "regular users", all giving User objects - with different semantics. – Klaws Jul 22 '20 at 14:01