Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do a query through a foreignkey in Django

How do I travel through multiple foreign keys in Django? I've tried everything I can think of from the django docs, but I'm obviously missed something (extreme newbie). I have models for scientists, experiments, and theories.

If I want to look at a particular Theory (let's call it 'relativity') and get a list of all of the emails of scientists working on it (kept in the normal django user model), how do I do this?


class Experiment(models.Model)

    experimenter = models.ForeignKey(Scientist)
    theory = models.ForeignKey(Theory)


class Theory(models.Model)

    name = models.CharField(max_length=100)

class Scientist(models.Model)

    user = models.ForeignKey(User, unique=True)
    institution = models.CharField(max_length=20, null=True, blank=True)

These are simplified versions of my models that I rewrote, so there are probably some errors in it, but the relationships are correct.

I've tried every kind of combinations of select_related(), get(), filter() but can't figure it out. Thanks in advance for your help!

like image 938
Tim Avatar asked Jul 29 '10 18:07

Tim


2 Answers

User.objects.filter(scientist__experiment__theory__name=u'relativity')
like image 136
Ignacio Vazquez-Abrams Avatar answered Nov 15 '22 08:11

Ignacio Vazquez-Abrams


Take a look at the Django documentation section about Lookups that span relationships. The net takeaway is:

To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want.

Ignacio's answer shows an example of using the double underscores on field names to span a relationship.

The other relevant portion of Django's documentation would be the Related objects section. Relationships in Django are asymmetrical in the way they are accessed. Forward/normal relationships are accessed as attributes of the models. Backward relationships are accessed:

Django also creates API accessors for the "other" side of the relationship -- the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute: b.entry_set.all().

like image 27
Matthew Rankin Avatar answered Nov 15 '22 06:11

Matthew Rankin