Search code examples
djangopostgresqlmanytomanyfield

Django ManyToMany reverse query with specific key


I have two tables. The first, is a basic user table. And the second is a table called Section.

def User(models.Model):
    ...
    is_teacher = models.BooleanField(default=False)
    ...

def Section(models.Model):
    ...
    teachers = models.ManyToManyField(User, related_name="teachers")
    students = models.ManyToManyField(User, related_name="students")
    is_active = models.BooleanField(default=True)
    ...

I would like to get all the student users (identified in the User table with is_teacher=False) which I know can be done easily with User.objects.filter(is_teacher=False).

I would like to also get the active section(s) for each user.

But, at the moment, I can't even seem to get the set of sections for the users.

I've tried:

students = User.objects.filter(is_teacher=False)
for s in students:
    print s.section_set.all()

But I'm getting an error that User object has no section_set. I'm guessing because the section has two many to many relationships with the User table (teachers and students), I probably have to specify the relationship more clearly (to follow the students one not the teachers one). But I'm not sure how to do this.


Solution

  • When defining related_name value, keep in mind that this a name for backwards relation (in your case — from User to Section). So, to keep your code clear and easy to understand, I'd recommend you to change the names like this:

    def Section(models.Model):
        ...
        teachers = models.ManyToManyField(User, related_name="sections_where_teacher")
        students = models.ManyToManyField(User, related_name="sections_where_student")
        is_active = models.BooleanField(default=True)
        ...
    

    Then using the relations looks like this:

    print s.sections_where_student.all()