2009-08-18 11 views

risposta

19
server = request.META.get('wsgi.file_wrapper', None) 
if server is not None and server.__module__ == 'django.core.servers.basehttp': 
    print('inside dev') 

Naturalmente, wsgi.file_wrapper potrebbe essere impostato su META, e hanno una classe da un modulo chiamato django.core.servers.basehttp da estrema coincidenza su un altro ambiente di server, ma spero che questo avrà coperto.

A proposito, ho scoperto questo facendo un modello sintatticamente non valida durante l'esecuzione sul server di sviluppo, e ha cercato roba interessante sulle sezioni Traceback e il Request information, quindi mi sto semplicemente modificando la mia risposta a corroborare con le idee di Nate .

+2

+1 per tentare effettivamente di rispondere alla domanda, ad esempio rilevando quale server sta servendo l'app Django, piuttosto che fare affidamento sulle impostazioni. Ad esempio, non c'è nulla che impedisca a qualcuno di eseguire in modalità DEBUG dietro qualcosa di diverso dal web server di sviluppo. –

+0

Un altro campo META specifico per server di sviluppo: SERVER_SOFTWARE ha stringhe 'WSGIServer' e' Python' su dev e tutto ciò che si configura nel server HTTP su "distribuito". – zgoda

+0

Vorrei aggiungere un 'getattr (server, '__module__', None)' nella seconda riga invece di andare direttamente alla notazione dot. Non si sa mai ... –

2

settings.DEBUG potrebbe essere True e in esecuzione con Apache o qualche altro server non di sviluppo. Funzionerà ancora. Per quello che posso dire, non c'è niente nell'ambiente di runtime che non esamina il pid e confronta i pids nel sistema operativo che ti daranno queste informazioni.

2

Una differenza tra lo sviluppo e l'ambiente di distribuzione sarà il server su cui è in esecuzione. Ciò che è esattamente diverso dipenderà dal tuo ambiente di sviluppo e di sviluppo.

Conoscendo i propri ambienti di sviluppo e distribuzione, è possibile utilizzare le variabili di richiesta HTTP per distinguere tra i due. Guarda request variables come request.META.HTTP_HOST, request.META.SERVER_NAME e request.META.SERVER_PORT e confrontali nei due ambienti.

Scommetto che troverete qualcosa di abbastanza ovvio che è diverso e può essere utilizzato per rilevare il vostro ambiente di sviluppo. Fai il test in settings.py e imposta una variabile che puoi usare altrove.

13

In genere ho impostato una variabile denominata environment e impostata su "DEVELOPMENT", "STAGING" o "PRODUCTION". All'interno del file delle impostazioni posso quindi aggiungere la logica di base per modificare quali impostazioni vengono utilizzate, in base all'ambiente.

EDIT: Inoltre, si può semplicemente utilizzare questa logica per includere diversi settings.py file che sostituiscono le impostazioni di base. Per esempio:

if environment == "DEBUG": 
    from debugsettings import * 
5

Basandosi sulla settings.DEBUG è la più elegante AFAICS modo in cui è utilizzato anche in Django base di codice in occasione.

Suppongo che quello che si vuole veramente sia un modo per impostare quel flag automaticamente senza che sia necessario aggiornarlo manualmente ogni volta che si carica il progetto sui server di produzione.

Per questo ho verificare il percorso di settings.py (in settings.py) per determinare quale server il progetto è in esecuzione su:

if __file__ == "path to settings.py in my development machine": 
    DEBUG = True 
elif __file__ in [paths of production servers]: 
    DEBUG = False 
else: 
    raise WhereTheHellIsThisServedException() 

Mente voi, si potrebbe anche preferire di fare questo controllo con variabili d'ambiente come suggerisce @Soviut. Ma come qualcuno che sta sviluppando su Windows e che serve su Linux controllando i percorsi dei file è stato più semplice che andare con le variabili di ambiente.

+1

beh, a parte le occasioni in cui potrei adottare la stessa convenzione di percorso nello sviluppo e nella produzione (che sarebbe la sconfitta), questo sembra essere il migliore per me. e +1 per 'WhereTheHellIsThisServedException' :-) – nemesisfixx

30

Ho inserito quanto segue nelle mie impostazioni.py per distinguere tra il server di sviluppo standard e la produzione:

import sys 
RUNNING_DEVSERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver') 

Ciò vale anche per convenzione.

(modificata per il commento di Daniel Magnusson)

+6

ho dovuto aggiungere se len (sys.argv)> 1: su prod server per farlo funzionare. –

+0

Questa è la risposta migliore in quanto non richiede una richiesta. Voglio fare questo per cablare in modo condizionale gli URL dei media –

+0

Puoi spiegare a cosa serve? Forse non capisco il problema, ma questa variabile memorizza se il sito è chiamato con manage.py runserver, giusto? E cosa fai con questo? Mi imbatto in questo post e questa sembra nuova roba che voglio imparare. Stavo cercando un modo per rilevare se sono su localhost, in tal caso attivare DEBUG (non sto cercando una risposta a riguardo in questo post) – aless80

4

mi sono imbattuto in questo problema solo ora, e finito per scrivere una soluzione simile a Aryeh Leib Taurog di. La mia principale differenza è che voglio distinguere tra un ambiente di produzione e un ambiente di sviluppo quando eseguo il server, ma anche quando eseguo alcuni script unici per la mia app (che corro come DJANGO_SETTINGS_MODULE = settings python [lo script]). In questo caso, è sufficiente verificare se argv [1] == runserver non è sufficiente. Quindi quello che mi è venuto in mente è di passare un ulteriore argomento da riga di comando quando eseguo il devserver, e anche quando eseguo i miei script, e cerco l'argomento in settings.py. Così il codice è simile al seguente:

if '--in-development' in sys.argv: 
    ## YES! we're in dev 
    pass 
else: 
    ## Nope, this is prod 
    pass 

poi, in esecuzione il server di Django diventa

python manage.py runserver [qualsiasi opzione che vuoi] --in-sviluppo

e l'esecuzione di mio script è facile come

DJANGO_SETTINGS_MODULE = impostazioni python [myscript] --in-sviluppo

Basta assicurarsi che l'argomento in più si passa lungo Doens Sono in conflitto con qualsiasi cosa django (in realtà uso il nome della mia app come parte dell'argomento). Penso che questo sia abbastanza decente, in quanto mi permette di controllare esattamente quando il mio server e gli script si comporteranno come prod o dev, e non sto facendo affidamento sulle convenzioni di qualcun altro, oltre al mio.

EDIT: manage.py lamenta se si passa le opzioni non riconosciute, quindi è necessario modificare il codice in settings.py essere qualcosa di simile

if sys.argv[0] == 'manage.py' or '--in-development' in sys.argv: 
    # ... 
    pass 

Anche se questo funziona, riconosco che non è il più elegante di soluzioni ...

1

Ispirato dalla risposta di Aryeh, il trucco ho ideato per mio uso è quello di guardare solo per il nome del mio script di gestione in sys.argv[0]:

USING_DEV_SERVER = "pulpdist/manage_site.py" in sys.argv[0] 

(mio caso d'uso è quello di attivare automaticamente l'autenticazione nativa Django quando si esegue il server di prova - durante l'esecuzione in Apache, anche sui server di sviluppo, tutta l'autenticazione per il mio progetto attuale è gestita tramite Kerberos)

2

io uso:

DEV_SERVERS = [ 
    'mymachine.local', 
] 

DEVELOPMENT = platform.node() in DEV_SERVERS 

che richiede di prestare attenzione a ciò che viene restituito da .node() sulle macchine. È importante che l'impostazione predefinita sia non di sviluppo in modo da non esporre accidentalmente informazioni di sviluppo sensibili.

È inoltre possibile esaminare more complicated ways of uniquely identifying computers.

3

Se si desidera passare automaticamente i file delle impostazioni in base all'ambiente di esecuzione , è possibile utilizzare solo qualcosa che differisce in ambiente, ad es.

from os import environ 
if environ.get('_', ''): 
    print "This is dev - not Apache mod_wsgi"   
5

Di solito questo funziona:

import sys 

if 'runserver' in sys.argv: 
    # you use runserver 
0

È possibile determinare se si sta eseguendo in WSGI (mod_wsgi, gunicorn, cameriera, ecc) vs. manage.py (runserver, prova, migrano, etc.) o qualsiasi altra cosa:

import sys 
WSGI = 'django.core.wsgi' in sys.modules 
Problemi correlati