You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django查询中何时添加“_set”?为何关联引用写法不同?

关于Django中外键关联是否需要加_set的判断方法

核心逻辑:区分正向与反向关联

在Django ORM中,是否需要加_set,完全取决于你是从关联关系的哪一端发起查询:

1. 正向关联(从外键所在模型指向关联模型)

如果查询是从包含ForeignKey字段的模型出发(比如从Tweet查关联的User),直接用外键字段名即可,不需要加_set。因为Tweet里明确定义了user字段,ORM能直接识别这个关联。

2. 反向关联(从被关联模型指向外键所在模型)

如果查询是从被外键关联的模型出发(比如从User查关联的所有Tweet),因为User模型本身没有直接的tweet字段,Django会自动生成一个反向关联管理器,默认命名规则是[关联模型名小写]_set,也就是tweet_set。这时候必须用这个带_set的名称来调用反向关联。


针对你的代码示例拆解

为什么prefetch_related用tweet_set

prefetch_related是在User的查询集上调用的,属于反向关联查询(从User拉取关联的Tweet数据),所以必须使用Django自动生成的反向管理器名称tweet_set。

为什么annotate里用tweet__favorite

annotate中使用的是Django ORM的跨表关联语法,这里的tweet是关联模型Tweet的小写名称。ORM会自动识别这种写法,通过User和Tweet的外键关联关系,去关联查询Tweet表中的favorite字段,不需要手动加_set后缀。


额外优化:自定义反向关联名称

如果你觉得默认的[模型名]_set不够直观,可以在定义外键时通过related_name参数指定自定义名称:

class Tweet(models.Model):
    user = models.ForeignKey("User", related_name="tweets")
    favorite = models.IntegerField(default=0)

之后,prefetch_related就可以用"tweets"代替tweet_set,但在annotate的跨表语法里,依然使用tweet__favorite(这里依赖的是模型名小写,而非自定义的related_name)。

内容的提问来源于stack exchange,提问作者y.dai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:57:40