Django 2.0+ 外键 on_delete 参数详解与使用指南

山海之间
山海之间
发布时间:2026-10-11 | 2人浏览过
原创

Django 2.0 引入了外键字段的强制性约束,要求开发者必须显式指定 on_delete 参数。该参数定义了当关联表中的记录被删除时,当前模型中对应字段的行为。本文详细解析了该参数的具体选项、适用场景及代码实现。

为什么必须指定 on_delete?

在 Django 2.0 之前,外键字段的删除行为默认为级联删除(CASCADE)。为了明确数据关系并防止意外删除,Django 2.0 强制要求显式定义此行为。若未指定 on_delete 参数,系统会抛出 TypeError 异常:

TypeError: __init__() missing 1 required positional argument: 'on_delete'

这一机制适用于 ForeignKey 和 OneToOneField,但 ManyToManyField 不包含此参数。

ForeignKey 与 OneToOneField 的实现

查看 Django 源码可知,ForeignKey 的构造函数强制要求 on_delete 参数:

class ForeignKey(ForeignObject):
  def __init__(self, to, on_delete, related_name=None, related_query_name=None,
         limit_choices_to=None, parent_link=False, to_field=None,
         db_constraint=True, **kwargs):
    super().__init__(to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs)

OneToOneField 继承自 ForeignKey,同样强制要求该参数:

class OneToOneField(ForeignKey):
  def __init__(self, to, on_delete, to_field=None, **kwargs):
    kwargs['unique'] = True
    super().__init__(to, on_delete, to_field=to_field, **kwargs)

相比之下,ManyToManyField 的构造函数中并未包含 on_delete 参数:

class ManyToManyField(RelatedField):
  def __init__(self, to, related_name=None, related_query_name=None,
         limit_choices_to=None, symmetrical=None, through=None,
         through_fields=None, db_constraint=True, db_table=None,
         swappable=True, **kwargs):
    super().__init__(**kwargs)

on_delete 可选值详解

on_delete 参数决定了删除关联数据时,当前表与其关联字段的交互方式。以下是常用选项:

  • models.CASCADE:级联删除。当关联表中的记录被删除时,当前表中关联该记录的字段也会被自动删除。这是最常见的行为。
  • models.DO_NOTHING:无操作。Django 不会执行任何额外操作,完全依赖数据库层面的约束(如外键约束)来处理删除。若数据库未设置级联删除,可能会引发 IntegrityError。
  • models.PROTECT:保护模式。当尝试删除关联记录时,Django 会抛出 ProtectedError 异常,阻止删除操作。适用于需要严格保护数据完整性的场景。
  • models.SET_NULL:设置为空。当关联记录被删除时,当前表的关联字段值被设置为 NULL。使用前必须确保该字段允许为空(null=True)。
  • models.SET_DEFAULT:设置为默认值。当关联记录被删除时,当前表的关联字段值被设置为默认值。使用前必须确保该字段设置了默认值(default=...)。
  • models.SET:设置为指定值。当关联记录被删除时,当前表的关联字段值被设置为指定的值或可调用对象的返回值。例如:models.SET('default_value') 或 models.SET(get_default_user)。

使用注意事项

在使用 SET_NULL 或 SET_DEFAULT 时,务必确保字段定义中包含了 null=True 或 default=...,否则会导致数据库约束冲突。此外,对于 OneToOneField,这些行为同样适用,但需注意唯一性约束的影响。

以上就是 Django 2.0+ 外键 on_delete 参数的详细内容,更多关于 Django 数据库设计的相关资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表