Where to put Django startup code?
Solution 1
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)
Solution 2
In Django 1.7+ if you want to run a startup code and,
1. Avoid running it in migrate, makemigrations, shell sessions, ...
2. Avoid running it twice or more
A solution would be:
file: myapp/apps.py
from django.apps import AppConfig
def startup():
# startup code goes here
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = "My Application"
def ready(self):
import os
if os.environ.get('RUN_MAIN'):
startup()
file: myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
This post is using suggestions from @Pykler and @bdoering
Solution 3
If you were using Apache/mod_wsgi for both, use the WSGI script file described in:
http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html
Add what you need after language translations are activated.
Thus:
import sys
sys.path.insert(0, '/usr/local/django/mysite')
import settings
import django.core.management
django.core.management.setup_environ(settings)
utility = django.core.management.ManagementUtility()
command = utility.fetch_command('runserver')
command.validate()
import django.conf
import django.utils
django.utils.translation.activate(django.conf.settings.LANGUAGE_CODE)
# Your line here.
django.core.management.call_command('syncdb', interactive=False)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Solution 4
You can create a custom command and write your code in the handle function. details here https://docs.djangoproject.com/en/dev/howto/custom-management-commands/
Then you can create a startup script that runs the django server then executes your new custom command.
Solution 5
If you are using mod_wsgi you can put it in the wsgi start app
Comments
-
Attila O. almost 2 years
I'd like to have these lines of code executed on server startup (both development and production):
from django.core import management management.call_command('syncdb', interactive=False)
Putting it in
settings.py
doesn't work, as it requires the settings to be loaded already.Putting them in a view and accessing that view externally doesn't work either, as there are some middlewares that use the database and those will fail and not let me access the view.
Putting them in a middleware would work, but that would get called each time my app is accessed. An possible solution might be to create a middleware that does all the job and then removes itself from
MIDDLEWARE_CLASSES
so it's not called anymore. Can I do that without too much monkey-patching? -
Attila O. about 14 yearsThanks for the quick response. This is exactly what I need.
-
Attila O. about 14 yearsThat'd look a little different as I use twod.wsgi. Also, I'd like to do this on the dev server too. And I wouldn't go as low level as apache. The idea is that I might not want to give the app developer ssh access to the server, but let him use the django admin by putting it in his startup code.
-
KillianDS over 12 yearsThis is a bad choice at it relies on a wrapper script around the server startup. What if someone forgets to start the server without the script?
-
Attila O. over 12 yearsI agree with @KillianDS. Still, it is a possibility. But then you'd have to use your wrapper as an entry point to the server, which may be any platform, mod_wsgi, app engine, tornado, etc.
-
Michael over 12 yearsAccording to stackoverflow.com/questions/6791911/…, this can be problematic. It is suggested there to put the start-up function in urls.py
-
Andrei over 12 yearsBoth middleware and urls.py do not run the startup code for management commands. Is there a better option?
-
krizajb over 11 yearsI am still getting multiple startup calls (printing random string, prints it multiple times)
-
KillianDS over 11 years@krizajB: note that this answer was written with django 1.0 or 1.1 in mind, there are currently better solutions available and maybe this solution is even not valid anymore in django 1.4. I'd update the answer with more recent techniques, but I've not done much django development recently so if someone knows a better modern technique, feel free to add it.
-
krizajb over 11 yearsBeen googling whole day, couldn't find anything that would work .. At least not for my case :(
-
Diego Barbaresco over 11 yearsThis doesn't seem to work in python 1.4... Any recommendations/workarounds?
-
krizajb over 11 yearsAs suggested by Michael, that seems to be the best solution at the moment (Django 1.4). There seems to be an update which isn't yet merged to the main branch, see github.com/ptone/django/blob/… . Oh, also be sure if you are using mod_wsgi to set it to deamon mode and if needed run it as a single process. See more here: code.google.com/p/modwsgi/wiki/IntegrationWithDjango keyword: WSGIDaemonProcess.
-
tr00st almost 10 yearsFound this question working from the other direction in 1.7 - ie: DB calls from AppConfig.ready() can have some really awkward side-effects. Specific use case is hooking up dynamic Models based on DB contents, so when tests are run, one can very quickly run into issues with missing tables. The middleware workaround may work best here, as it will only be called on the first request - ie: when we're on the right DB. We can then hook up something on the testing side to ensure that the init code gets called there too.
-
Klaas van Schelven over 9 yearsNote that the linked solution for Django 1.7 explicitly warns against running any SQL (which appears to have been the original question).
-
Incerteza about 9 yearsAgain, how to do that - write the code to be executed on startup of the App?
-
binithb over 4 yearswho will set the environment varianle RUN_MAIN?
-
Joseph Bani about 4 years@binithb apparently django does at runtime