Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: query all items that have a foreign key point to them

Tags:

django

I have two models:

class A(models.Model):
    name = models.CharField(max_length=100, unique=True)

class B(models.Model):
    a = models.ForeignKey(A)

In Django, how can I select all objects of class 'A' that have an object of class B that points to them? For example, if the database contains these three entries of class 'A':

A, named "one"
A, named "two"
A, named "three"

And two entries of class B:

B, points to "two"
B, points to "three"

I want to select classes "two" and "three" of type A.

like image 637
Dylan Klomparens Avatar asked Nov 15 '13 17:11

Dylan Klomparens


2 Answers

You can do it like this:

a_qs = A.objects.filter(b = b) 

where b is an object of class B and the b= refers to the lowercase model name which you want to query the reverse relationship.

Read more on lookups that span relationships here. It covers how to do a reverse lookup on models' ForeignKey attributes

Edit:

If you are looking for all objects which do not have any ForeignKey objects pointing to them, you can use exclude and __isnull

a_qs = A.objects.exclude(b__isnull = True) 
like image 135
karthikr Avatar answered Nov 09 '22 15:11

karthikr


This worked for me:

a_qs = A.objects.filter(b__a__isnull=False).distinct()

It gives only the objects of A which has a B object pointing to it. Use a__isnull=False to check whether a ForeignKey exists. If it does, it can, by definition, only point to A. Duplicates are removed with distinct().

When a related_name parameter has been set, e.g.

class A(models.Model):
    name = models.CharField(max_length=100, unique=True)

class B(models.Model):
    a = models.ForeignKey(A, related_name='b_list')

this worked:

a_qs = A.objects.filter(b_list__a__isnull=False).distinct() 
like image 20
GCru Avatar answered Nov 09 '22 14:11

GCru