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)

Asked By: bmjrowe

||

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)
Answered By: bmjrowe

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!

Answered By: Sergi7