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

Django中的Forward Foreign Key与Reverse Foreign Key是什么?

Django中的正向外键(Forward Foreign Key)与反向外键(Reverse Foreign Key)定义

这两个是Django社区常用的非官方术语,官方文档里没有专门定义,但在讨论查询优化(比如select_related/prefetch_related)时经常被提到,结合你给出的模型代码,具体解释如下:

正向外键(Forward Foreign Key)

  • 核心逻辑:在直接声明ForeignKey字段的模型中,这个字段本身就代表正向外键关系。
  • 对应你的模型:Product模型里的category = models.ForeignKey(...)就是正向外键——Product主动关联到Category,从Product到Category的关联方向就是"正向"。
  • 查询示例:拿到一个Product实例后,直接通过product.category就能获取对应的分类对象。这类查询属于多对一关联,底层可以用SQL JOIN一次性拉取数据,所以适合用select_related优化N+1问题:
# 用select_related优化正向查询,避免重复查询数据库
products = Product.objects.select_related('category').all()
for p in products:
    print(p.category.name)  # 不会触发额外的SQL查询

反向外键(Reverse Foreign Key)

  • 核心逻辑:从被ForeignKey关联的目标模型,反过来关联到声明外键的模型的关系,Django会自动为这类模型生成反向关联属性。
  • 对应你的模型:Category没有直接声明外键,但Django自动生成了product_set属性(默认命名规则是[关联模型名小写]_set),通过它可以获取该分类下的所有Product实例,这就是反向外键关系。
  • 查询示例:拿到一个Category实例后,用category.product_set.all()获取所有关联产品。这类查询属于一对多反向关联,需要额外查询再拼接结果,所以适合用prefetch_related优化:
# 用prefetch_related优化反向查询,避免N+1问题
categories = Category.objects.prefetch_related('product_set').all()
for c in categories:
    print([p.name for p in c.product_set.all()])  # 不会触发额外的SQL查询
  • 自定义反向名称:你可以通过ForeignKey的related_name参数修改默认的反向关联名称,比如把Product的外键改成:
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')

之后就可以用category.products.all()代替默认的product_set了。

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:25:21