Where to Put Django Startup Code

Execute code when Django starts ONCE only?

Update from Pykler's answer below: Django 1.7 now has a hook for this


Don't do it this way.

You don't want "middleware" for a one-time startup thing.

You want to execute code in the top-level urls.py. That module is imported and executed once.

urls.py

from django.confs.urls.defaults import *
from my_app import one_time_startup

urlpatterns = ...

one_time_startup()

Where in Django can I run startup code that requires models?

The problem is that you import .models at the top of your file. This means that, when the file app.py file is loaded, Python will load the models.py file when it evalutes that line. But that is too early. You should let Django do the loading properly.

You can move the import in the def ready(self) method, such that the models.py file is imported when ready() is called by the Django framework, like:

from django.apps import AppConfig

class Pqawv1Config(AppConfig):
name = 'pqawV1'

def ready(self):
from .models import KnowledgeBase
to_load = KnowledgeBase.objects.order_by('-timestamp').first()
# Here should go the file loading code

Where to put Django startup code?

Write middleware that does this in __init__ and afterwards raise django.core.exceptions.MiddlewareNotUsed from the __init__, django will remove it for all requests :). __init__ is called at startup by the way, not at the first request, so it won't block your first user.

There is talk about adding a startup signal, but that won't be available soon (a major problem for example is when this signal should be sent)

Related Ticket: https://code.djangoproject.com/ticket/13024

Update: Django 1.7 includes support for this. (Documentation, as linked by the ticket)

Correct place to put extra startup code in django?

I would put them in settings.py. In the past, I have put system checks like this:

try:
from local_settings import *
except ImportError:
print "Missing %s" % os.path.join(PROJECT_ROOT, "local_settings.py")

if DEBUG:
for p in [PROJECT_ROOT, MEDIA_ROOT, THEME_DIR, ADMIN_MEDIA_ROOT] + list(TEMPLATE_DIRS):
p = os.path.normpath(p)
if not os.path.exists(p):
print "Missing path: %s" % p

Executing code on startup in Django 1.7

For Django>=1.7 you can use the AppConfig.ready() callback:

https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready

For previous versions, see this answer.

If you are using the AppConfig.ready() method:

1) Create a myapp/apps.py module and subclass the AppConfig. For example:

from django.apps import AppConfig

class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
...

2) Edit myapp/__init__.py and register your app config:

default_app_config = 'myapp.apps.MyAppConfig'

See https://docs.djangoproject.com/en/1.7/ref/applications/#configuring-applications for details.

django + uwsgi, where to place my startup code?

Put your startup code in a separate file, for example startup.py and then alter these two files:

manage.py

# some code
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[project name].settings")
if __name__ == "__main__":
import startup
# the rest of the code

[project name]/wsgi.py

# some code
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[project name].settings")
import startup
# the rest of the code

Note the order: import is always after environ setting (might not be important, depends on what startup does).

In Django1.7 you can use ready function per application. Read this:

https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready

Run startup code in the parent with Django and Gunicorn

This is old but in Gunicorn version 19.0 and above, you can create a custom script to run your application and include the startup code that you need there. Here is an example script using a django app:

#!/usr/bin/env python

"""
Script for running Gunicorn using our WSGI application
"""

import multiprocessing

from gunicorn.app.base import BaseApplication

from myapp.wsgi import application # Must be imported first

class StandaloneApplication(BaseApplication):
"""Our Gunicorn application."""

def __init__(self, app, options=None):
self.options = options or {}
self.application = app
super().__init__()

def load_config(self):
config = {
key: value for key, value in self.options.items()
if key in self.cfg.settings and value is not None
}
for key, value in config.items():
self.cfg.set(key.lower(), value)

def load(self):
return self.application

if __name__ == '__main__':
gunicorn_options = {
'bind': '0.0.0.0:8080',
'workers': (multiprocessing.cpu_count() * 2) + 1,
}

# Your startup code here

StandaloneApplication(application, gunicorn_options).run()



Related Topics



Leave a reply



Submit