2010-05-06 7 views
46

Ich mag diese Zeilen Code auf Serverstart ausgeführt haben (sowohl Entwicklung und Produktion):Wohin mit Django-Startup-Code?

from django.core import management 
management.call_command('syncdb', interactive=False) 

es in settings.py Putting nicht funktioniert, wie es die Einstellungen erfordert bereits geladen werden.

Wenn Sie sie in eine Ansicht einfügen und extern auf diese Ansicht zugreifen, funktioniert das auch nicht, da es einige Middlewares gibt, die die Datenbank verwenden. Diese werden fehlschlagen und nicht auf die Ansicht zugreifen.

Sie in eine Middleware zu setzen würde funktionieren, aber das würde jedes Mal aufgerufen werden, wenn auf meine App zugegriffen wird. Eine mögliche Lösung könnte darin bestehen, eine Middleware zu erstellen, die den gesamten Job erledigt und sich dann von MIDDLEWARE_CLASSES entfernt, so dass sie nicht mehr aufgerufen wird. Kann ich das tun, ohne zu viel Affen zu flicken?

Antwort

53

Schreiben Sie Middleware, die dies in __init__ tut und danach django.core.exceptions.MiddlewareNotUsed von der __init__ erhöhen, Django wird es für alle Anfragen entfernen :). __init__ wird beim Start übrigens nicht bei der ersten Anfrage aufgerufen, so dass es Ihren ersten Benutzer nicht blockiert.

Es ist die Rede über ein Startsignal geben, aber das wird bald nicht mehr verfügbar sein (ein großes Problem ist zum Beispiel, wenn dieses Signal gesendet werden soll)

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

Update: Django 1.7 enthält Unterstützung dafür. (Documentation, wie von der Fahrkarte)

+0

Danke für die schnelle Antwort. Das ist genau das, was ich brauche. –

+4

Das ist ein schöner Trick, von dem ich nicht wusste. –

+2

Laut http://stackoverflow.com/questions/6791911/execute-code-when-django-starts-once-only kann dies problematisch sein. Es wird vorgeschlagen, die Startfunktion in urls.py – Michael

1

Wenn Sie mod_wsgi verwenden Sie es in der wsgi Start app

4

Wenn Sie Apache wurden unter Verwendung setzen können/mod_wsgi für beide, verwenden Sie die WSGI Skript-Datei beschrieben in:

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

hinzufügen, was Sie brauchen nach Sprache Übersetzungen aktiviert werden.

So:

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() 
+0

Das würde ein bisschen anders aussehen, wie ich twod.wsgi verwende. Außerdem würde ich das gerne auch auf dem Dev-Server machen. Und ich würde nicht so niedrig wie Apache gehen. Die Idee ist, dass ich dem App-Entwickler ssh keinen Zugriff auf den Server geben möchte, aber lass ihn den django admin verwenden, indem er ihn in seinen Startup-Code steckt. –

3

Sie können einen benutzerdefinierten Befehl erstellen und Ihren Code in der Griff Funktion schreiben. Details hier https://docs.djangoproject.com/en/dev/howto/custom-management-commands/

Dann können Sie ein Startskript erstellen, das den Django-Server ausführt und dann Ihren neuen benutzerdefinierten Befehl ausführt.

+1

Dies ist eine schlechte Wahl, da es sich auf ein Wrapper-Skript um den Serverstart stützt. Was passiert, wenn jemand vergisst, den Server ohne das Skript zu starten? – KillianDS

+0

Ich stimme @ @ KillianDS (http://stackoverflow.com/users/243870/killiands). Trotzdem ist es eine Möglichkeit. Aber dann müssten Sie Ihren Wrapper als Einstiegspunkt für den Server verwenden, der jede Plattform, Mod_wsgi, App-Engine, Tornado usw. sein könnte. –

0

Hier ist, wie ich um das fehlende Startsignal für Django arbeiten: https://github.com/lsaffre/djangosite/blob/master/djangosite/models.py Der Code, der zu meinem djangosite Projekt spezifisch ist dort genannt wird, aber der Trick, um es durch das Schreiben eine spezielle App (basierend auf einem gecallt Idee von Ross McFarland) sollte für andere Umgebungen funktionieren. Luc