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

Django模型外键字段:类名带引号与不带引号的差异及选型

Django模型外键:带引号与不带引号类名的差异及选择

示例场景

情况1:关联类在前,两种写法均有效

带引号写法

class Category(models.Model):
    name = models.CharField(max_length=50)

class Product(models.Model):     # Here
    category = models.ForeignKey("Category", on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

不带引号写法

class Category(models.Model):
    name = models.CharField(max_length=50)

class Product(models.Model):     # Here
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

情况2:关联类在后,仅带引号写法可行

带引号写法(正常运行)

class Product(models.Model):     # Here
    category = models.ForeignKey("Category", on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

class Category(models.Model):
    name = models.CharField(max_length=50)

不带引号写法(报错)

class Product(models.Model):     # Error
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

class Category(models.Model):
    name = models.CharField(max_length=50)

报错信息:

NameError: name 'Category' is not defined

问题解答

1. 带引号与不带引号类名的差异

  • 不带引号的类名:属于直接引用Python类对象,要求定义外键时,关联类已经被Python解释器加载(即代码顺序在当前类之前)。因为Python逐行执行代码,若解析当前模型时关联类未定义,会直接抛出NameError。
  • 带引号的类名:属于延迟引用,传入的是字符串形式的类名。Django会在所有模型加载完成后再解析该字符串,匹配对应的模型类。这种写法不依赖代码定义顺序,还支持跨应用模型关联(格式为"应用名.模型类名")。

2. 定义外键时的写法选择

  • 若关联模型在当前模型之前定义,两种写法均可,不带引号的写法更符合Python常规引用习惯,直观易懂。
  • 若关联模型在当前模型之后定义,或需要关联其他应用的模型,必须使用带引号的延迟引用写法,避免未定义错误。
  • 团队协作或复杂项目中,统一使用带引号的写法能减少因代码顺序调整引发的问题,兼容性更强。

内容的提问来源于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.07.20 11:22:53