Django模型字段中的类名,带引号或不带引号,以建立外键关系。

huangapple go评论83阅读模式
英文:

The class name with or without quotes in a Django model field to have foreign key relationship

问题

以下是翻译好的部分:

  1. 在Django模型字段中,类名带引号和不带引号之间有什么区别?

  2. 在Django模型字段中,应该使用带引号还是不带引号的类名来建立外键关系?

英文:

I can set Category with or without quotes to ForeignKey() as shown below:

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)

Or:

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)

And, I know that I can set Category with quotes to ForeignKey() before Category class is defined as shown below:

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)

And, I know that I cannot set Category without quotes to ForeignKey() before Category class is defined as shown below:

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)

Then, I got the error below:

> NameError: name 'Category' is not defined

My questions:

  1. What is the difference between the class name with or without quotes in a Django model field to have foreign key relationship?

  2. Which should I use, the class name with or without quotes in a Django model field to have foreign key relationship?

答案1

得分: 1

以下是要翻译的内容:

What is the difference between the class name with or without quotes in a Django model field to have foreign key relationship?

在Django模型字段中,使用带引号和不带引号的类名之间有什么区别?

You can not reference a variable before that variable is defined. Indeed, you can not use:

你不能在变量被定义之前引用该变量。实际上,你不能使用:

wrong

错误

print(a)
a = 42

because at that time, 42 is not defined. The same holds for classes, as you found out. You can not refer to a class that should is not defined yet. This is a consequence of Python seeing classes as "first-class citizens": a class is just an object. It does not require some special compilation steps.

因为在那个时候,42 还没有定义。对于类来说也是一样的,正如你所发现的那样。你不能引用一个尚未定义的类。这是Python将类视为“一等公民”的结果:类只是一个对象。它不需要特殊的编译步骤。

This thus means that you can not refer to a model that has to be defined in the rest of the code. Another problem are cyclic imports where two models would import each other, and thus result in an ImportError.

因此,这意味着你不能引用在代码的其余部分中定义的模型。另一个问题是循环导入,其中两个模型会彼此导入,从而导致ImportError

In order to fix this, Django allows to specify the model as a string literal when you refer to it. Normally you notate this as ''app_name.ModelName'' with app_name the name of the app where the model is defined. If you refer to a model in the same app as the one you are defining, you can omit the string literal.

为了解决这个问题,Django允许在引用模型时将模型指定为字符串字面值。通常你会将它标记为''app_name.ModelName'',其中*app_name*是定义模型的应用程序的名称。如果你引用的模型与你正在定义的模型在同一个应用程序中,你可以省略字符串字面值。

Django will thus, after all the models are loaded, try to resolve the string literals and replace the string literals in the model object with a reference to the real model class.

因此,在加载所有模型之后,Django将尝试解析字符串字面值,并将模型对象中的字符串字面值替换为对真实模型类的引用。

Which should I use, the class name with or without quotes in a Django model field to have foreign key relationship?

我应该在Django模型字段中使用带引号还是不带引号的类名来创建外键关系?

Both will eventually, after that the models are loaded, result in the same modeling and the same references hold, so there is no difference.

两者最终在加载模型后将得到相同的建模结果,并且引用也是相同的,因此没有区别。

If you refer to models that will be defined later in the file, or in modules that would result in cyclic imports, then we don't have much choice, then the string literal is the way to "knot the tie".

如果你引用的模型将在文件后面定义,或者在可能导致循环导入的模块中定义,那么我们没有太多选择,字符串字面值是"打个结"的方式。

An advantage of using the identifier and not the string literal is that most IDEs follow the identifiers and if you decide to rename a class, it automatically renames the uses. IDEs can also see if you refer to an identifier not in scope. PyCharm with the Django extension also "understands" the string literal notation and thus can do something equivalent, but that is only because they implemented such logic in the IDE.

使用标识符而不是字符串字面值的优点是,大多数集成开发环境会跟踪标识符,如果你决定重命名一个类,它会自动重命名引用。集成开发环境还可以看到你是否引用了超出范围的标识符。带有Django扩展的PyCharm也“理解”字符串字面值表示法,因此可以执行等效的操作,但这仅仅是因为他们在IDE中实现了这样的逻辑。

Conclusion: Using an identifier is thus slightly better than a string literal if that is possible. If you use models later defined in the file, or you would introduce cyclic imports, you have to use a string literal.

结论:如果可能的话,使用标识符要略微好于使用字符串字面值。如果你在文件后面使用了后定义的模型,或者引入了循环导入,那么你必须使用字符串字面值。

英文:

> What is the difference between the class name with or without quotes in a Django model field to have foreign key relationship?

You can not reference a variable before that variable is defined. Indeed, you can not use:

# wrong
print(a)
a = 42

because at that time, 42 is not defined. The same holds for classes, as you found out. You can not refer to a class that should is not defined yet. This is a consequence of Python seeing classes as "first-class citizens": a class is just an object. It does not require some special compilation steps.

This thus means that you can not refer to a model that has to be defined in the rest of the code. Another problem are cyclic imports where two models would import each other, and thus result in an ImportError.

In order to fix this, Django allows to specify the model as a string literal when you refer to it. Normally you notate this as <code>'<i>app_name</i>.<i>ModelName</i>'</code> with app_name the name of the app where the model is defined. If you refer to a model in the same app as the one you are defining, you can omit the string literal.

Django will thus, after all the models are loaded, try to resolve the string literals and replace the string literals in the model object with a reference to the real model class.

> Which should I use, the class name with or without quotes in a Django model field to have foreign key relationship?

Both will eventually, after that the models are loaded, result in the same modeling and the same references hold, so there is no difference.

If you refer to models that will be defined later in the file, or in modules that would result in cyclic imports, then we don't have much choice, then the string literal is the way to "knot the tie".

An advantage of using the identifier and not the string literal is that most IDEs follow the identifiers and if you decide to rename a class, it automatically renames the uses. IDEs can also see if you refer to an identifier not in scope. PyCharm with the Django extension also "understands" the string literal notation and thus can do something equivalent, but that is only because they implemented such logic in the IDE.

Conclusion: Using an identifier is thus slightly better than a string literal if that is possible. If you use models later defined in the file, or you would introduce cyclic imports, you have to use a string literal.

huangapple
  • 本文由 发表于 2023年5月29日 22:00:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357984.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定