Django查询中的单下划线是否像双下划线一样使用?

9

最近我在代码中犯了一个错别字,发现得到了相同的结果,因此想知道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个回答

12

这两个字段恰好同时存在。

foreign_key_idMyModel 对象上自动生成的一个列,而 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. 

这对objects.filter调用有什么影响?我猜__id会使用连接处理数据库过滤,而_id会返回MyModel表中的所有对象,并在Django内部进行过滤。或者它们都在数据库内部进行过滤,但__id会涉及两个表,而_id只涉及一个表吗? - Ian Burnette
1
@blackfedora 你有查看 SQL 查询的工具。 - wRAR
谢谢,通过 .query 检查,看起来无论哪种方式生成的 MySQL 查询都是相同的。 - Ian Burnette

1
foreign_key_idMyModel的(隐藏)字段名称,foreign_key__id是对foreign_key字段引用的任何模型上的字段的引用。换句话说,它是外键字段的一个具体细节。

1
根据我的观察,如果只是过滤或获取foreign_key__id,Django足够聪明,不会使用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的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接