Jorge Leitao
Jorge Leitao

Reputation: 20163

Query parents which have child in django

So, I'm struggling in the following situation:

Consider the models:

class A(models.Model):
    foo = models.IntegerField(default=0)

class B(models.Model):
    a_models = models.ForeignKey('A', related_name='b_models')
    bar = models.IntegerField(default=0)

class bChild(B):
    bla = models.IntegerField(default=0)

if I have an instance of A, a_instance, and I want to retrieve all the instances of class B which have a relation with it, I can use

all_b_models = a_instance.b_models.all()

My question is: what if I want to retrieve only the ones which also have bChilds:

all_bChild_models = a_instance.b_models.filter(???)

what should I put in "???"?

I'm not finding any documentation to this. One thing I think works is to use:

??? = pk__in=bChild.objects.all().values_list('pk')

However, since django creates an implicit backward relationship for Multi-table inheritance, I was wondering if there is a simpler query.

Thanks, Jorge

Upvotes: 1

Views: 1886

Answers (2)

Raunak Agarwal
Raunak Agarwal

Reputation: 7238

Is there a reason why you want to fetch bChild object only via A instance when you could simply do this:

result = bChild.objects.filter(a_models = a)

Your approach wouldn't work you need a flat list to filter by pk:

all_bChild_models = a_instance.b_models.filter(pk__in = bChild.objects.values_list('pk', flat=True))

Upvotes: 1

Jorge Leitao
Jorge Leitao

Reputation: 20163

Well, I figured it out by myself.

Apparently, django considers that pk is null if the model does not have a child.

So, one can use:

all_bChild_models = a_instance.b_models.filter(bchild__pk__isnull=False)

this will return all the b models which have a bChild model pointing at it.

Upvotes: 2

Related Questions