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

1πŸ‘

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 '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 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.

Leave a comment