在Django中过滤多对多关系

时间:2022-10-05 13:09:52

I have this structure of model objects:

我有这种模型对象的结构:

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

This is the query I'm trying to get:
I want to get all the B objects of object A, then in each B object to perform a comparison between the D object and the c.d object.

这是我想要获得的查询:我想获取对象A的所有B对象,然后在每个B对象中执行D对象和c.d对象之间的比较。

I know that simply move on the B collection with for loop and make this comparison. But I dived on the ManyToMany relation, then I noticed I can do the following:

我知道只需使用for循环移动B集合并进行此比较。但我潜入了ManyToMany关系,然后我注意到我可以做到以下几点:

bObjects = A.objects.all().b

q = bObjects.filter(c__d=None)

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

这是有效的,它给了我所有带有无字段的c对象。但是,当我尝试以下内容时:

q = bObjects.filter(c__d=d)

It gives me d not defined, but d is an object like c in the object B.

它给了我没有定义,但d是对象B中的c之类的对象。

What can be the problem? I'll be happy if you suggest further way to do this task. I generally I'm trying to write my query in a single operation with many to many sub objects and not using loops.

可能是什么问题?如果您建议进一步完成此任务,我会很高兴。我通常在尝试使用多个子对象并且不使用循环的单个操作中编写查询。

1 个解决方案

#1


6  

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

q = bObjects.filter(c_d = d)//我没有定义。但是d是对象B中的c之类的对象。

Try this:

尝试这个:

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 in those ways:

至于下面你的评论中的问题,你可以通过以下方式获得1个sql查询而不是100个:

1) if you can express your selection of A objects in terms of a query (for example a.price<10 and a.weight>20) use this:

1)如果您可以根据查询表达您对A对象的选择(例如a.price <10和a.weight> 20),请使用以下命令:

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

or this:

或这个:

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

2) if you just have a python list of A objects, use this:

2)如果你只有一个A对象的python列表,请使用:

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

#1


6  

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

q = bObjects.filter(c_d = d)//我没有定义。但是d是对象B中的c之类的对象。

Try this:

尝试这个:

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 in those ways:

至于下面你的评论中的问题,你可以通过以下方式获得1个sql查询而不是100个:

1) if you can express your selection of A objects in terms of a query (for example a.price<10 and a.weight>20) use this:

1)如果您可以根据查询表达您对A对象的选择(例如a.price <10和a.weight> 20),请使用以下命令:

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

or this:

或这个:

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

2) if you just have a python list of A objects, use this:

2)如果你只有一个A对象的python列表,请使用:

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