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
相关产品推荐
相关产品推荐

