Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Accessing Many to Many object through another Many to Many relationship

I have simplified my models down a to make it clearer what I am trying to do.

(models.py in app Teams)

 from django.db import models
 from django.contrib.auth.models import User
 import datetime

class Team(models.Model):
    users = models.ManyToManyField(User)
    team_title = models.CharField(max_length=200)
    team_description = models.CharField(max_length=200)

    def __unicode__(self):
        return self.team_title

(models.py in app Documents)

from django.db import models
import datetime

class Document(models.Model):    
   teams = models.ManyToManyField("Teams.Team", blank=True)
   document_title = models.CharField(max_length=200)
   document_description = models.TextField()

def __unicode__(self):
    return self.document_title

What I want to achieve is getting a list of users who have are associated with a Document by first getting all the teams associated with the document and then from this getting all the users associated with those teams.

My attempts so far have gone something like this

(view.py in app Documents)

from django.contrib.auth.models import User
from Documents.models import *
from Teams.models import *

def docUsers(request, doc_id):
    current_document = Documents.objects.get(pk = doc_id)
    associated_users = current_document.teams.all().users

    ....

Error: 'QuerySet' object has no attribute 'users'

associated_users = current_document.items.all().users.all()

Error: 'QuerySet' object has no attribute 'users'

associated_users = current_document.items.users.all()

Error: 'ManyRelatedManager' object has no attribute 'users'

Am I going about this the wrong way?

like image 347
Finglish Avatar asked Apr 18 '12 18:04

Finglish


1 Answers

Well, yes. current_document.teams.all() is a queryset - more or less, a list - of Teams. It doesn't make sense to ask for current_document.teams.all().users, as a queryset doesn't itself have a 'users' attribute, hence the error. users is an attribute of each Team element within that queryset. So, one way of doing it would be to iterate through the queryset and ask for the users associated with each team.

However, that would be hopelessly inefficient - one database call for each team. A much better way is to ask the database directly: give me all the users who are in teams associated with the current document. Like this:

User.objects.filter(team__documents=current_document)
like image 101
Daniel Roseman Avatar answered Oct 01 '22 18:10

Daniel Roseman