2015-02-12 21 views
5

Voglio fare in modo che il server di sviluppo Django faccia qualcosa prima che inizi a funzionare. Per fare questo, ho creato una nuova applicazione, aggiunto al top della INSTALLED_APPS, e quindi creato un file management/commands/runserver.py in app con il seguente codice:Perché viene eseguito due volte nel server dev di Django?

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) 

(La cosa che davvero voglio fare è più complicato piuttosto che scrivere una riga su stdout, naturalmente, ma questo è l'esempio più semplice che dimostra il problema.Il motivo per cui sostituisco run, anziché handle o qualche altro metodo, è perché ho bisogno di self.addr per essere già impostato quando viene eseguito questo codice.)

Quando corro ./manage.py runserver, la riga "Informazioni sull'avvio in esecuzione su 127.0.0.1" non viene visualizzata una volta, bensì due volte o il server inizia a funzionare. Perché sta succedendo questo e cosa si può fare al riguardo?

+0

Molto probabilmente non si vuole modificare il comando di marcia , dai un'occhiata alla funzionalità del gancio di avvio Django menzionata in questa risposta. https://stackoverflow.com/a/16111968/742390 La funzione di ricaricamento automatico di django runserver esegue due volte le operazioni, ma è innocua e viene utilizzata solo in dev. Non dovresti usare runserver in produzione, in produzione il codice di avvio verrà eseguito una sola volta. – Pykler

+0

Questo era solo per lo sviluppo locale, in realtà. – Taymon

+0

In questo caso non dovresti preoccuparti del fatto che funziona due volte, dal momento che è davvero solo dev. Se vuoi scrivere il tuo codice in modo tale che funzioni anche in produzione, la modifica del comando di esecuzione non funzionerà quando finalmente la si distribuisce sotto uwsgi o gunicorn. – Pykler

risposta

6

Il processo di auto-ricarica è risultato essere il colpevole; scopre che il processo autoreload ottiene gli stessi argomenti e passa attraverso lo stesso processo di inizializzazione dell'originale. La soluzione era quella di avere il codice pre-server di eseguire solo se non è in esecuzione nel processo generato dal autoreloader, che può essere rilevata attraverso una variabile di ambiente:

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

Il server di sviluppo locale esegue un processo separato per l'auto-reloader. È possibile disattivare il processo di ricarica automatica passando il flag --noreload.

python manage.py runserver --noreload 
Problemi correlati