views:

38

answers:

2

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!

+1  A: 
User.objects.filter(scientist__experiment__theory__name=u'relativity')
Ignacio Vazquez-Abrams
Thanks for your help and not making fun of me :)
Tim
+2  A: 

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().

Matthew Rankin
Thanks for the link Matthew, I was having a hard time figuring out the correct phrases to look for.
Tim
Tim — If you're interested in a good book on Django to get started, I'd recommend either (or both) *The Definitive Guide to Django* 2nd ed or *Django 1.0 Website Development* 2nd ed.
Matthew Rankin