Erez
Erez

Reputation: 2655

Django - Following ForeignKey relationships "backward" for entire QuerySet

is it possible to follow ForeignKey relationships backward for entire querySet?

i mean something like this:

x = table1.objects.select_related().filter(name='foo')
x.table2.all()

when table1 hase ForeignKey to table2.

in https://docs.djangoproject.com/en/1.2/topics/db/queries/#following-relationships-backward i can see that it works only with get() and not filter()

Thanks

Upvotes: 2

Views: 2030

Answers (3)

Krzysztof Szularz
Krzysztof Szularz

Reputation: 5249

You basically want to get QuerySet of different type from data you start with.

class Kid(models.Model):
    mom = models.ForeignKey('Mom')
    name = models.CharField…

class Mom(models.Model):
    name = models.CharField…

Let's say you want to get all moms having any son named Johnny.

Mom.objects.filter(kid__name='Johnny')

Let's say you want to get all kids of any Lucy.

Kid.objects.filter(mom__name='Lucy')

Upvotes: 6

Risadinha
Risadinha

Reputation: 16666

You can also use values() to fetch specific values of a foreign key reference. With values the select query on the DB will be reduced to fetch only those values and the appropriate joins will be done.

To re-use the example from Krzysztof Szularz:

jonny_moms = Kid.objects.filter(name='Jonny').values('mom__id', 'mom__name').distinct()

This will return a dictionary of Mom attributes by using the Kid QueryManager.

Upvotes: 1

rofls
rofls

Reputation: 5115

You should be able to use something like:

for y in x:
y.table2.all()

But you could also use get() for a list of the unique values (which will be id, unless you have a different specified), after finding them using a query.

So,

x = table1.objects.select_related().filter(name='foo')
for y in x:
   z=table1.objects.select_related().get(y.id)
   z.table2.all()

Should also work.

Upvotes: 1

Related Questions