Django ORM外键过滤传入实例与id结果一致的原因是什么?
Django外键过滤传实例与传主键结果一致的原因
这是Django ORM针对外键字段查询设计的内置适配逻辑,本质上两种写法生成的SQL查询完全一致,所以返回结果相同,具体原因如下:
- 外键字段的存储本质
你在模型中定义的ForeignKey类型字段,实际在对应数据库表中存储的是关联模型的主键值,默认存储列名为[外键字段名]_id。你示例中的ForeignKeyField字段,对应数据库实际存储列就是foreignkeyfield_id,存的就是关联模型的主键ID。 - ORM的自动解析逻辑
当你使用外键字段作为过滤条件时:- 如果传入的是关联模型的实例对象(也就是你示例中的
self),Django ORM会自动提取该实例的主键值,代入到最终生成的SQL查询条件中 - 如果直接传入主键值(也就是你示例中的
self.id),ORM会直接把该值代入SQL查询条件
两种写法最终生成的SQL完全相同,类似如下结构:
- 如果传入的是关联模型的实例对象(也就是你示例中的
SELECT * FROM comment WHERE foreignkeyfield_id = [当前实例的主键值]
因此查询返回的结果没有任何区别。
- 补充使用建议
日常开发更推荐直接传实例的写法,一是更简洁不需要手动取主键,二是如果实例可能为None的场景下,直接传NoneORM会自动解析为IS NULL条件,不会像手动取.id一样抛出AttributeError异常。
内容的提问来源于stack exchange,提问作者djain
相关产品推荐
相关产品推荐

