models.ForeignKey 是 Django ORM 用于定义 外键(多对一关系)的字段类型。它提供了多种参数来控制数据库行为和 ORM 逻辑。下面是所有常见的方法和参数:


一、ForeignKey 的参数

ForeignKey(
    to,                 # 关联的模型(必填)
    on_delete,          # 级联删除规则(必填)
    related_name=None,  # 反向查询名称
    related_query_name=None,  # 反向查询时的字段名
    limit_choices_to=None,  # 限制可选项(通常用于 Django Admin)
    to_field=None,      # 关联的字段(默认为主键)
    db_constraint=True, # 是否在数据库创建外键约束
    db_index=True,      # 是否创建索引(默认True)
    editable=True,      # 是否允许在表单中编辑
    null=False,         # 是否允许为空
    blank=False,        # Django 表单是否可以为空
    unique=False,       # 是否唯一
    help_text='',       # 帮助文本
    verbose_name=None,  # 管理后台显示名称
    error_messages=None # 自定义错误信息
)

二、ForeignKey 参数详解

1. to(必填,关联的模型)

指向外键的目标模型,可以使用:

  • 直接类名:ForeignKey(User, ...)
  • 字符串(避免循环导入问题):ForeignKey("auth.User", ...)
class Post(models.Model):
    author = models.ForeignKey("auth.User", on_delete=models.CASCADE)

2. on_delete(必填,删除级联规则)

外键关联的对象被删除 时,当前表的行为:

选项 作用
CASCADE 级联删除,删除关联对象时,当前对象也删除
PROTECT 保护模式,阻止删除(抛异常)
SET_NULL 设为 NULL(需 null=True
SET_DEFAULT 设为默认值(需 default=...
SET() 自定义逻辑,如 SET(some_function)
DO_NOTHING 什么都不做,数据库自行处理

示例

class Comment(models.Model):
    post = models.ForeignKey("Post", on_delete=models.CASCADE)  # 文章删除,评论也删除

3. related_name(反向查询)

默认情况下,Django 反向查询用 modelname_set,但可以自定义:

class Post(models.Model):
    pass

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")

# 反向查询
post = Post.objects.get(id=1)
post.comments.all()  # 而不是 post.comment_set.all()

4. related_query_name(反向查询的字段名)

用于 反向查询时在 filter()exclude() 等查询 时的名称:

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments", related_query_name="comment")

# 反向查询
Post.objects.filter(comment__content="test")  # 而不是 comment_set

5. limit_choices_to(限制可选项)

在 Django Admin 限制外键可选项

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, limit_choices_to={"status": "published"})
  • 仅允许选择 status="published"Post
  • 仅限 Django Admin,不影响 ORM 查询

6. to_field(指定外键字段)

默认外键关联 id,但可以指定其他字段:

class Post(models.Model):
    slug = models.SlugField(unique=True)

class Comment(models.Model):
    post = models.ForeignKey(Post, to_field="slug", on_delete=models.CASCADE)
  • 现在 Comment 关联 post.slug,而不是 post.id

7. db_constraint(是否创建数据库外键约束)

  • 默认 True,创建数据库外键约束
  • 如果你只是为了逻辑上的外键,但不希望数据库创建外键约束(如分库分表):
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, db_constraint=False)

8. db_index(是否创建索引)

  • 默认 True,Django 自动为外键字段创建数据库索引。
  • 可禁用索引(适用于大数据量,不常用此外键查询):
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, db_index=False)

9. editable(是否允许编辑)

  • editable=False 隐藏 Django Admin 和表单中的外键字段,但不会影响数据库:
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, editable=False)

10. nullblank

  • null=True:数据库允许 NULL(适用于 SET_NULL
  • blank=True:表单可以不填此字段
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.SET_NULL, null=True, blank=True)

11. unique(唯一性约束)

  • 默认 False,可以有多个相同的外键
  • unique=True 让外键字段唯一(类似 OneToOneField):
class Profile(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, unique=True)

12. help_text(提示文本)

在 Django Admin 显示提示信息

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, help_text="选择要关联的文章")

13. verbose_name(管理后台显示名称)

  • 设置 Django Admin 字段的友好名称
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, verbose_name="关联文章")

14. error_messages(自定义错误信息)

class Comment(models.Model):
    post = models.ForeignKey(
        Post,
        on_delete=models.CASCADE,
        error_messages={
            "null": "必须选择一篇文章",
            "invalid": "无效的文章 ID"
        }
    )

三、总结

参数 作用
to 指定关联的模型
on_delete 级联删除规则(CASCADESET_NULLPROTECT 等)
related_name 反向查询时的名称
related_query_name 用于 filter() 查询的字段名称
limit_choices_to 限制可选项(用于 Django Admin)
to_field 指定外键关联的字段(默认是 id
db_constraint 是否创建数据库外键约束
db_index 是否创建索引
editable 是否允许在 Django Admin 编辑
null / blank 允许为空(数据库 / Django 表单)
unique 是否唯一
help_text Django Admin 的提示信息
verbose_name Django Admin 的字段名称
error_messages 自定义错误消息

这样,我们就掌握了 Django ForeignKey 的所有参数及用法 🚀

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐