Django模型字段中的类名是否带引号以具有外键关系

luaexgnf  于 2023-05-30  发布在  Go
关注(0)|答案(1)|浏览(167)

我可以将Category带引号或不带引号设置为ForeignKey(),如下所示:

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)

而且,我知道我可以在定义Category类之前将Category用引号设置为ForeignKey(),如下所示:

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)

而且,我知道在定义Category类之前,我不能将不带引号的Category设置为ForeignKey(),如下所示:

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)

然后,我得到了下面的错误:
名称错误:名称'类别'未定义
我的问题:

  1. Django模型字段中的类名是否带引号有什么区别?
    1.我应该使用哪一个,在Django模型字段中使用带引号的类名还是不带引号的类名来建立外键关系?
ecfsfe2w

ecfsfe2w1#

Django模型字段中的类名是否带引号有什么区别?
在定义变量之前不能引用该变量。实际上,您不能用途:

# wrong
print(a)
a = 42

因为在那个时候,42没有被定义。这同样适用于类,正如你所发现的。不能引用尚未定义的类。这是Python将类视为“一等公民”的结果:类只是一个对象。它不需要一些特殊的编译步骤。
因此,这意味着您不能引用必须在代码的其余部分中定义的模型。另一个问题是 * 循环导入 *,其中两个模型将相互导入,从而导致ImportError
为了解决这个问题,Django允许在引用模型时将其指定为字符串文字。通常,您将其标记为'app_name.ModelName',其中 app_name 是定义模型的应用程序的名称。如果您引用的模型与您正在定义的模型在同一个应用程序中,则可以省略字符串文字。
因此,在所有模型加载之后,Django将尝试解析字符串文字,并将模型对象中的字符串文字替换为对真实的模型类的引用。
我应该使用哪一个,在Django模型字段中使用带引号的类名还是不带引号的类名来建立外键关系?
在加载模型之后,这两种方法最终会产生相同的建模和相同的引用,因此没有区别。
如果您引用的模型将在文件中稍后定义,或者在模块中将导致循环导入,那么我们没有太多选择,那么字符串字面量是“打结”的方式。
使用标识符而不是字符串文字的优点是大多数IDE都遵循标识符,如果您决定重命名一个类,它会自动重命名使用。IDE还可以查看是否引用了不在作用域中的标识符。带有Django扩展的PyCharm也“理解”字符串文字符号,因此可以执行一些等效的操作,但这只是因为它们在IDE中实现了这样的逻辑。

结论:因此,如果可能的话,使用标识符比使用字符串字面量稍微好一点。如果使用文件中稍后定义的模型,或者引入循环导入,则必须使用字符串文字。

相关问题