Django ORM 外键 ForeignKey 详解:定义、跨应用引用与删除策略

宋时安
宋时安
发布时间:2026-10-13| 6人浏览过
原创

本文深入解析Django中ForeignKey外键的定义与使用。涵盖跨应用模型引用、自引用评论实现,重点详解CASCADE、PROTECT、SET_NULL等六种on_delete删除策略及其适用场景,帮助开发者掌握Django数据库关系管理的核心机制。

外键

Django外键基础与InnoDB支持

在MySQL数据库中,主要存在InnoDB和MyISAM两种存储引擎。其中,InnoDB引擎支持外键约束,这一特性使得ORM框架在处理表间关联关系时具备强大的能力。因此,本节将重点介绍外键在Django框架中的具体应用方式。

ForeignKey类的定义格式为class ForeignKey(to, on_delete, **options)。其中,第一个参数to指定所引用的模型类;第二个参数on_delete规定当被引用的模型数据被删除时,当前字段应采取的处理策略,常见的选项包括CASCADE(级联删除)和SET_NULL(设为空)等。以下通过一个具体案例进行说明:假设存在User和Article两个模型,一个User用户可以发表多篇文章,而每篇文章Article仅对应一位作者,且通过外键建立关联。相关的模型定义代码如下:

ForeignKey定义与模型关联示例


class User(models.Model):
  username = models.CharField(max_length=20)
  password = models.CharField(max_length=100)

class Article(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()

  author = models.ForeignKey("User",on_delete=models.CASCADE)

上述代码使用ForeignKey定义了模型间的关联关系。在Article模型实例中,可以通过author属性直接操作对应的User模型对象,这种设计极大地提升了开发便利性。具体的使用示例代码如下:

通过外键属性访问关联对象


article = Article(title='abc',content='123')
author = User(username='张三',password='111111')
article.author = author
article.save()

# 修改article.author上的值
article.author.username = '李四'
article.save()

为何在使用ForeignKey后,可以通过author属性直接访问到对应的user对象?其底层机制在于,Django在Article表中自动添加了一个名为属性名_id的字段(例如,若外键名为author,则生成author_id字段)。该字段作为外键,存储了对应作者的主键值。当通过article.author进行访问时,Django实际上是先通过author_id查询到相关数据,再从User表中提取该条记录,最终封装成一个模型对象返回。

若需引用其他应用(app)中的模型,在传递to参数时,应采用app_name.model_name的格式进行指定。以上述为例,若User模型位于user应用,而Article模型位于article应用,则引用时的示例代码如下:

跨应用模型的外键引用


# User模型在user这个app中
class User(models.Model):
  username = models.CharField(max_length=20)
  password = models.CharField(max_length=100)

# Article模型在article这个app中
class Article(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()

  author = models.ForeignKey("user.User",on_delete=models.CASCADE)

当模型的外键引用其自身时,to参数可以设置为'self'或直接使用模型名称。在论坛开发场景中,评论功能通常支持二级评论,即用户可以对其他评论进行回复。在定义此类模型时,需使用外键引用自身。示例代码如下:

自引用外键与二级评论实现


class Comment(models.Model):
  content = models.TextField()
  origin_comment = models.ForeignKey('self',on_delete=models.CASCADE,null=True)
  # 或者
  # origin_comment = models.ForeignKey('Comment',on_delete=models.CASCADE,null=True)

外键删除操作:

外键删除策略on_delete详解

当模型使用了外键时,若被引用的模型数据被删除,系统应执行何种操作?这可以通过on_delete参数进行指定。可选的类型如下:

  1. CASCADE(级联删除):若外键所指向的数据被删除,则当前这条数据也会随之被删除。
  2. PROTECT(保护模式):只要当前数据引用了外键所指向的数据,则禁止删除外键所指向的数据,否则将抛出ProtectedError异常。
  3. SET_NULL(设为空):若外键所指向的数据被删除,则将当前数据中的该外键字段设置为空值。若选择此选项,前提是该外键字段必须允许为空(null=True)。
  4. SET_DEFAULT(设置默认值):若外键所指向的数据被删除,则将当前数据中的该外键字段设置为默认值。若选择此选项,前提是该外键字段必须指定了默认值(default=...)。
  5. SET()(动态设置):若外键所指向的数据被删除,系统将获取SET函数中提供的值作为该外键的新值。SET函数可以接收一个可调用对象(如函数或方法)。若传入的是可调用对象,Django将在运行时调用该对象,并将返回结果作为外键的值。
  6. DO_NOTHING(无操作):Django不采取任何额外动作,完全依赖数据库级别的约束来处理删除行为。

以上内容涵盖了Django中ForeignKey外键的核心用法与删除策略,希望对各位的学习有所帮助。欢迎继续关注本站获取更多技术分享。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。