How to execute a decorator function at startup in a Django/Python Application?
Question:
I have a number of classes for which I wish to run a decorator function on. As I am aware decorators only run when the class/function/whatever they label is loaded into the code.
e.g.
def decorator(cls):
print("Decorator executed")
return cls
@decorator
class Example:
pass
Example()
How can I trigger the decorator function on all the classes a decorator labels at startup of the django application without having to load each class separately? (or without having knowledge of the classes for which a decorator labels)
Answers:
Solution Update:
I had a bunch of classes for which I wanted to run a decorator function on and they all contained ‘Model’ in their classname. Decorators on classes are executed upon an import of the given class so as a work around I made a function (which ran at startup) to import all classes containing ‘Model’ in their classname and as a byproduct the decorator function ran against all of these classes.
import glob
import importlib.util
def execute_decorator_against_classes():
for filename in glob.iglob("**/*Model.py",
recursive=True):
module_name = filename.split("/")
module_name = module_name[len(module_name) - 1]
module_name = module_name[:module_name.rfind('.py')]
spec = importlib.util.spec_from_file_location(module_name,
filename)
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
You could have used a deploy command instead, in case your only purpose was to perform an action on the deploy process of the project.
In order to do this, you must have a project structure that contains a management/commands
folder inside any of your apps that are inside the INSTALLED_APPS
variable (located at the project’s settings.py
)
Now, you could create a <<custom_name>>.py file inside management/commands
folder, where you define the python code to be executed on the deployment.
You can find examples here:
https://docs.djangoproject.com/en/4.1/howto/custom-management-commands/
Last but not least, you must trigger the execution of this deploy command. This can be done with the following statement:
On a terminal in your project root folder, type the following:
python3 manage.py <<custom_name>>
This will execute the
Please keep in mind you don’t have to add the .py extension when calling the deploy command.
Hope this helps!
I have a number of classes for which I wish to run a decorator function on. As I am aware decorators only run when the class/function/whatever they label is loaded into the code.
e.g.
def decorator(cls):
print("Decorator executed")
return cls
@decorator
class Example:
pass
Example()
How can I trigger the decorator function on all the classes a decorator labels at startup of the django application without having to load each class separately? (or without having knowledge of the classes for which a decorator labels)
Solution Update:
I had a bunch of classes for which I wanted to run a decorator function on and they all contained ‘Model’ in their classname. Decorators on classes are executed upon an import of the given class so as a work around I made a function (which ran at startup) to import all classes containing ‘Model’ in their classname and as a byproduct the decorator function ran against all of these classes.
import glob
import importlib.util
def execute_decorator_against_classes():
for filename in glob.iglob("**/*Model.py",
recursive=True):
module_name = filename.split("/")
module_name = module_name[len(module_name) - 1]
module_name = module_name[:module_name.rfind('.py')]
spec = importlib.util.spec_from_file_location(module_name,
filename)
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
You could have used a deploy command instead, in case your only purpose was to perform an action on the deploy process of the project.
In order to do this, you must have a project structure that contains a management/commands
folder inside any of your apps that are inside the INSTALLED_APPS
variable (located at the project’s settings.py
)
Now, you could create a <<custom_name>>.py file inside management/commands
folder, where you define the python code to be executed on the deployment.
You can find examples here:
https://docs.djangoproject.com/en/4.1/howto/custom-management-commands/
Last but not least, you must trigger the execution of this deploy command. This can be done with the following statement:
On a terminal in your project root folder, type the following:
python3 manage.py <<custom_name>>
This will execute the
Please keep in mind you don’t have to add the .py extension when calling the deploy command.
Hope this helps!