tags:

views:

216

answers:

2
class Project(models.Model):
    title = models.CharField()  

class Job(models.Model):
    name = models.CharField()
    user = models.ForeignKey(User)
    project = models.ForeignKey(Project)

I have many jobs for each project. How do i get a list of all users of all jobs of a project?
I came up with this:

users = set()
for job in project.job_set.all():
    users.add(job.user)

Is there an easier way without explicitely looping through every job?

+3  A: 

Use Django's join syntax and start from your User model instead:

users = User.objects.filter(job_set__project=project).distinct()
Joe Holloway
this line doesn't seem to work - says Cannot resolve keyword 'job_set' into field. Choices are:
barin
i figured that instead of job_set there should be job. Thanx it works!
barin
Based on the code in your question, since you haven't specified a `related_name` in the `ForeignKey`, it should have defaulted to `job_set`. If you do this instead: `user = models.ForeignKey(User, related_name='jobs')`, then you would filter based on `jobs__project=project`
Joe Holloway
it's interesting because i havent specified a related name and it still goes by the name of the model and not the name of the field. I tried it on other models too. Maybe it's becuase im using alpha version of django
barin
Very strange. I'd be careful since it disagrees with the documentation. It could be a bug, but I don't know how that one could have slipped past their unit tests. http://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name
Joe Holloway
+1  A: 

Alternatively, you could use a ManyToMany relation from Project to User through the Job model which is in effect a join model:

class Project(models.Model):
   users = models.ManyToManyField(User, through='Job')
   ...

And then simply do:

project.users.all()
kibitzer