2015-02-12 9 views
5

Ich möchte, dass der Django-Entwicklungsserver etwas macht, bevor er startet. Dazu habe ich eine neue App, fügte er an die Spitze der INSTALLED_APPS, und erstellt dann eine management/commands/runserver.py Datei in der App mit dem folgenden Code:Warum wird im Django-Dev-Server zweimal aufgerufen?

from django.contrib.staticfiles.management.commands.runserver import Command as RunserverCommand 
class Command(RunserverCommand): 
    def run(self, *args, **options): 
     self.stdout.write('About to start running on ' + self.addr) 
     super(Command, self).run(*args, **options) 

(Das, was ich will eigentlich zu tun ist komplizierter als eine Zeile in stdout zu schreiben, natürlich, aber das ist das einfachste Beispiel, das das Problem demonstriert.Der Grund, dass ich run statt handle oder eine andere Methode überschreibe, ist, weil ich self.addr bereits gesetzt werden muss, wenn dieser Code ausgeführt wird.)

Wenn ich ./manage.py runserver ausführen, erscheint die Zeile "Über den Start auf 127.0.0.1 starten" nicht einmal, aber zweimal bef oder der Server wird gestartet. Warum passiert das und was kann dagegen getan werden?

+0

Sie höchstwahrscheinlich nicht wollen, den Startbefehl bearbeiten , werfen Sie einen Blick auf die Django Startup Hook Funktionalität, die in dieser Antwort erwähnt wird. https://StackOverflow.com/a/16111968/742390 Die automatische Neuladefunktion von Django Runserver, wird Dinge zweimal ausführen, aber es ist harmlos und nur in Dev verwendet. Sie sollten runserver nicht in der Produktion verwenden, in der Produktion wird der Startcode nur einmal ausgeführt. – Pykler

+0

Dies war eigentlich nur für die lokale Entwicklung. – Taymon

+0

In diesem Fall sollten Sie sich nicht viel sorgen, dass es zweimal läuft, da es wirklich nur dev ist. Sie möchten Ihren Code so schreiben, dass er auch in der Produktion funktioniert. Die Bearbeitung des Befehls run funktioniert nicht, wenn Sie ihn schließlich unter uwsgi oder gunicorn bereitstellen. – Pykler

Antwort

6

Der Auto-Reloader-Prozess erwies sich als der Übeltäter; stellt sich heraus, dass der Autoreload-Prozess dieselben Argumente erhält und denselben Initialisierungsprozess wie das Original durchläuft. Die Lösung war der Pre-Server-Code haben, nur dann ausgeführt, wenn es nicht in dem Prozess durch die autoreloader gelaicht ausgeführt wird, die durch eine Umgebungsvariable festgestellt werden kann:

import os 
from django.contrib.staticfiles.management.commands.runserver import Command as RunserverCommand 
class Command(RunserverCommand): 
    def run(self, *args, **options): 
     if os.environ.get('RUN_MAIN') != 'true': 
      self.stdout.write('About to start running on ' + self.addr) 
     super(Command, self).run(*args, **options) 
8

Der lokale Entwicklungsserver führt einen separaten Prozess für den automatischen Wiederlader aus. Sie können den Vorgang zum automatischen Neuladen ausschalten, indem Sie das Flag --noreload übergeben.

python manage.py runserver --noreload