2

I want to run some code when my Django server starts-up in order to clean up from the previous end of the server. How can I run some code once and only once at startup before the server processes any requests. I need to access the database during this time.

I've read a couple of things online that seem a bit outdated and are also not guaranteed to run only once.

Update

I've looked at the suggested answer by looking into the ready function. That appears to work, but it is documented that you should not access the database there (https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready)

There are many suggestions at Execute code when Django starts ONCE only?, but since that post is a few years old, I thought there might be some additional solutions.

This looks promising

from django.dispatch import receiver
from django.db.backends.signals import connection_created

@receiver(connection_created)
def my_receiver(connection, **kwargs):
    with connection.cursor() as cursor:
        # do something to the database

    connection_created.disconnect(my_receiver)

Any other thoughts?

2
  • If it need not be at the start of the server but can be run before the server start you could just make a custom management command and run that before starting the server. Commented Jul 10 at 18:03
  • I want it to run a little more automated when the server starts Commented Jul 10 at 19:54

1 Answer 1

3

This is often done with the .ready() method [Django-doc] of any of the AppConfig classes [Django-doc] of an installed app. So if you have an app named app_name, you can work with:

# app_name/apps.py

from django.apps import AppConfig


class MyAppConfig(AppConfig):
    # …

    def ready(self):
        # my management command
        # …

This will run after the models of all INSTALLED_APPS are loaded, so you can do management commands. This is also often used to hook signals to models.

5
  • 1
    Thanks. Found more info here: stackoverflow.com/questions/33814615/…, to prevent it from running twice. I used ` if os.environ.get('RUN_MAIN'):` Commented Jul 9 at 19:22
  • @PeterKronenberg: well Django only reloads in development mode. It is possible that if you use gunicorn for example, it spawns multiple processes, but once per process thus. Commented Jul 9 at 19:32
  • Will that check work in other environments as well? I want to ensure that it only runs once, prior to taking any requests Commented Jul 9 at 22:20
  • 1
    RUN_MAIN is AFAIK specific to Django's runserver, it won't work with other methods of execution. Your check for this will depend on how you are deploying the app. For gunicorn for example, check out this answer.
    – Vegard
    Commented Jul 10 at 4:38
  • I've updated my question Commented Jul 10 at 17:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.