Django查询单下划线像双下划线一样?
我最近在代码里打错了一个字母,结果发现程序的表现跟之前一样。所以我想知道在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)
因为underscore
和double_underscore
在内存中是两个不同的对象,所以我认为这就是为什么underscore == double_underscore
会返回False的原因。
1
foreign_key_id
是 MyModel
里的一个(隐藏的)字段名,而 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.