views:

280

answers:

3

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?

+12  A: 

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)

KillianDS
Thanks for the quick response. This is exactly what I need.
Attila Oláh
That's a nice trick I wasn't aware of.
Will McCutchen
A: 

If you r using mod_wsgi you can put it in the wsgi start app

aviah
A: 

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()
Graham Dumpleton
That'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.
Attila Oláh