Django查询单下划线像双下划线一样?

9 投票
3 回答
3226 浏览
提问于 2025-04-17 16:18

我最近在代码里打错了一个字母,结果发现程序的表现跟之前一样。所以我想知道在Django查询中,单下划线和双下划线有什么区别。

>>> underscore = MyModel.objects.filter(foreign_key_id=var)
>>> double_underscore =  MyModel.objects.filter(foreign_key__id=var)
>>> underscore == double_underscore
False
>>> list(underscore) == list(double_underscore)
True

我不太确定在比较查询集时用的是哪种相等方法,但当我把它们转换成Python列表时,发现里面的元素完全一样。有没有人能帮我解释一下这是怎么回事?

3 个回答

1

根据我的观察,Django很聪明,如果只是过滤或者获取foreign_key__id,它就不会去做连接查询(join)与外键(ForeignKey)。你可以用下面的代码来测试一下:

>>> print(MyModel.objects.filter(foreign_key_id=var).query)
>>> print(MyModel.objects.filter(foreign_key__id=var).query)

因为underscoredouble_underscore在内存中是两个不同的对象,所以我认为这就是为什么underscore == double_underscore会返回False的原因。

1

foreign_key_idMyModel 里的一个(隐藏的)字段名,而 foreign_key__id 是指向某个模型中与 foreign_key 字段相关的字段。换句话说,它是外键字段的一个具体细节。

12

这两个字段恰好都存在。

foreign_key_id 是在 MyModel 对象上自动创建的一个列,而 foreign_key__id 是外键表本身的 ID。

这两个值其实是一样的。

MyModel1.foreign_key_id == 5  # this is stored on the model
                              # and does not require a lookup.
MyModel1.foreign_key.id == 5  # this is stored on the target table
                              # and requires a DB hit. 

撰写回答