Filter out many-many relationships in Django

I have this structure of model objects:

Grade A:
b = models.ManyToManyField("B") 
Grade B:
 c = models.ForeignKey("C") d = models.ForeignKey("D") 
Grade C:
 d = models.ForeignKey("D") 

This is the request I'm trying to get:
I want to get all objects B of object A, and then in each object B compare between object D and object cd

I know that we just go to collection B with a for loop and do this comparison. But I plunged into the ManyToMany relation, then I noticed that I can do the following:

 bObjects = A.objects.all().b q = bObjects.filter(c__d=None) 

This works, it gives me all the objects c with the None d field. But when I try the following:

 q = bObjects.filter(c__d=d) 

This gives me d not defined, but d is an object of type c in object B.

What could be the problem? I will be glad if you suggest a further way to complete this task. Usually I try to write my query in one operation with many, many helper objects and not using loops.

+7
django django-models
source share
1 answer

q = bObjects.filter(c_d=d) // Give me d not defined. but d is an object similar to c in object B.

Try the following:

 from django.db.models import F q = bObjects.filter(c__d=F('d')) 

As for the question from your comment below, you can have 1 sql query instead of 100 this way:

1) if you can express your choice of A objects in terms of a query (e.g. a.price <10 and a.weight> 20), use this:

 B.objects.filter(a__price__lt=10, a__weight__gt=20, c__d=F('d')) 

or that:

 B.objects.filter(a__in=A.objects.filter(price__lt=10, weight__gt=20), c_d=F('d')) 

2) if you only have a list of Python objects A, use this:

 B.objects.filter(a__pk__in=[a.pk for a in your_a_list], c__d=F('d')) 
+6
source share