英文:
The class name with or without quotes in a Django model field to have foreign key relationship
问题
以下是翻译好的部分:
-
在Django模型字段中,类名带引号和不带引号之间有什么区别?
-
在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:
-
What is the difference between the class name with or without quotes in a Django model field to have foreign key relationship?
-
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论