Io tendo ad usare SQLite quando faccio Django Sviluppo, ma su un server live qualcosa di più robusto è Spesso necessario ( MySQL / PostgreSQL , ad esempio ) . Invariabilmente, ci sono altre modifiche da apportare alle impostazioni di Django : Diverse posizioni/intensità di registrazione, Percorsi multimediali, ecc.
Come gestite tutte queste modifiche per rendere la distribuzione un processo semplice e automatizzato?
Aggiornamento:Le configurazioni di Django sono state rilasciate, il che è probabilmente un'opzione migliore per la maggior parte delle persone rispetto a farlo manualmente.
Se preferisci fare le cose manualmente, la mia precedente risposta vale ancora:
Ho più file di impostazioni.
settings_local.py
- Configurazione specifica dell'host, come nome del database, percorsi dei file, ecc.settings_development.py
: configurazione utilizzata per lo sviluppo, ad es. DEBUG = True
.settings_production.py
: configurazione utilizzata per la produzione, ad es. SERVER_EMAIL
.Li lego tutti insieme con un file settings.py
che importa prima settings_local.py
e poi uno degli altri due. Decide quale caricare da due impostazioni all'interno di settings_local.py
- DEVELOPMENT_HOSTS
e PRODUCTION_HOSTS
. settings.py
chiama platform.node()
per trovare il nome host del computer su cui è in esecuzione, quindi cerca quel nome host negli elenchi e carica il secondo file di impostazioni a seconda dell'elenco in cui trova il nome host.
In questo modo, l'unica cosa di cui devi davvero preoccuparti è mantenere il file settings_local.py
aggiornato con la configurazione specifica dell'host e tutto il resto viene gestito automaticamente.
Guarda un esempio qui .
Personalmente, io uso un singolo settings.py per il progetto, ho appena cercato il nome host in cui si trova (le mie macchine di sviluppo hanno nomi host che iniziano con "gabriel" quindi ho solo questo:
import socket
if socket.gethostname().startswith('gabriel'):
LIVEHOST = False
else:
LIVEHOST = True
poi in altre parti ho cose come:
if LIVEHOST:
DEBUG = False
PREPEND_WWW = True
MEDIA_URL = 'http://static1.grsites.com/'
else:
DEBUG = True
PREPEND_WWW = False
MEDIA_URL = 'http://localhost:8000/static/'
e così via. Un po 'meno leggibile, ma funziona bene e salva dover manipolare più file di impostazioni.
Alla fine di settings.py ho il seguente:
try:
from settings_local import *
except ImportError:
pass
In questo modo, se voglio sovrascrivere le impostazioni predefinite, devo semplicemente mettere settings_local.py proprio accanto a settings.py.
Ho due file. settings_base.py
che contiene le impostazioni comuni/predefinite e che viene controllato nel controllo del codice sorgente. Ogni distribuzione ha un settings.py
separato, che esegue from settings_base import *
all'inizio e quindi esegue l'override secondo necessità.
Il modo più semplicistico che ho trovato è stato:
1) usa default settings.py per lo sviluppo locale e 2) Crea un production-settings.py che inizia con:
import os
from settings import *
E poi basta scavalcare le impostazioni che differiscono nella produzione:
DEBUG = False
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
....
}
}
Un po 'correlato, per il problema della distribuzione di Django stesso con più database, si potrebbe voler dare un'occhiata a Djangostack . Puoi scaricare un programma di installazione completamente gratuito che ti permette di installare Apache, Python, Django, ecc. Come parte del processo di installazione ti permettiamo di selezionare il database che vuoi usare (MySQL, SQLite, PostgreSQL). Utilizziamo estensivamente gli installer durante l'automazione interna delle distribuzioni (possono essere eseguiti in modalità non assistita).
Ho il mio file settings.py in una directory esterna. In questo modo, non viene controllato nel controllo del codice sorgente o sovrascritto da una distribuzione. Inserisco questo nel file settings.py sotto il mio progetto Django, insieme a qualsiasi impostazione predefinita:
import sys
import os.path
def _load_settings(path):
print "Loading configuration from %s" % (path)
if os.path.exists(path):
settings = {}
# execfile can't modify globals directly, so we will load them manually
execfile(path, globals(), settings)
for setting in settings:
globals()[setting] = settings[setting]
_load_settings("/usr/local/conf/local_settings.py")
Nota: questo è molto pericoloso se non ci si può fidare di local_settings.py.
Bene, io uso questa configurazione:
Alla fine di settings.py:
#settings.py
try:
from locale_settings import *
except ImportError:
pass
E in locale_settings.py:
#locale_settings.py
class Settings(object):
def __init__(self):
import settings
self.settings = settings
def __getattr__(self, name):
return getattr(self.settings, name)
settings = Settings()
INSTALLED_APPS = settings.INSTALLED_APPS + (
'gunicorn',)
# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings
Oltre ai file di impostazioni multiple menzionati da Jim, tendo anche a inserire due impostazioni nel mio file settings.py in alto BASE_DIR
e BASE_URL
impostato sul percorso del codice e l'URL alla base del sito, tutte le altre impostazioni sono modificati per aggiungersi a questi.
BASE_DIR = "/home/sean/myapp/"
es. MEDIA_ROOT = "%smedia/" % BASEDIR
Quindi, quando si sposta il progetto, devo solo modificare queste impostazioni e non cercare l'intero file.
Suggerisco anche di guardare fabric e Capistrano (strumento Ruby, ma può essere usato per distribuire applicazioni Django) che facilitano l'automazione della distribuzione remota.
Questo è un post più vecchio ma penso che se aggiungo questo library
utile semplificherà le cose.
pip install Django-configurations
Quindi sottoclassi le configurazioni incluse. Classe di configurazione nel file settings.py del tuo progetto o qualsiasi altro modulo che stai utilizzando per memorizzare le costanti delle impostazioni, ad esempio:
# mysite/settings.py
from configurations import Configuration
class Dev(Configuration):
DEBUG = True
Imposta la variabile d'ambiente Django_CONFIGURATION
sul nome della classe appena creata, ad es. in ~/.bashrc
:
export Django_CONFIGURATION=Dev
e la variabile di ambiente Django_SETTINGS_MODULE
al percorso di importazione del modulo come al solito, ad es. in bash:
export Django_SETTINGS_MODULE=mysite.settings
In alternativa fornisce l'opzione --configuration
quando si usano i comandi di gestione di Django seguendo le linee dell'opzione predefinita della riga di comando --settings
di Django, ad esempio:
python manage.py runserver --settings=mysite.settings --configuration=Dev
Per consentire a Django di utilizzare la tua configurazione ora devi modificare lo script manage.py o wsgi.py per usare le versioni di Django-configurations delle funzioni di avvio appropriate, ad es. un tipico manage.py usando le configurazioni di Django sarebbe simile a questo:
#!/usr/bin/env python
import os
import sys
if __== "__main__":
os.environ.setdefault('Django_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('Django_CONFIGURATION', 'Dev')
from configurations.management import execute_from_command_line
execute_from_command_line(sys.argv)
Nota nella riga 10 non usiamo lo strumento comune Django.core.management.execute_from_command_line
ma invece configurations.management.execute_from_command_line
.
Lo stesso vale per il tuo file wsgi.py, ad esempio:
import os
os.environ.setdefault('Django_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('Django_CONFIGURATION', 'Dev')
from configurations.wsgi import get_wsgi_application
application = get_wsgi_application()
Qui non usiamo la funzione predefinita Django.core.wsgi.get_wsgi_application
ma invece configurations.wsgi.get_wsgi_application
.
Questo è tutto! Ora puoi utilizzare il tuo progetto con manage.py e il tuo server WSGI preferito.
Penso che dipenda dalla dimensione del sito se è necessario passare dall'uso di SQLite, ho usato SQLite con successo su diversi siti live più piccoli e funziona alla grande.
Io uso l'ambiente:
if os.environ.get('WEB_MODE', None) == 'production' :
from settings_production import *
else :
from settings_dev import *
Credo che questo sia un approccio molto migliore, perché alla fine hai bisogno di impostazioni speciali per il tuo ambiente di test, e puoi facilmente aggiungerlo a questa condizione.
Così tante risposte complicate!
Ogni file settings.py viene fornito con:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Io uso quella directory per impostare la variabile DEBUG come questa (con la directory dove è il tuo codice dev):
DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
DEBUG = True
Quindi, ogni volta che viene spostato il file settings.py, DEBUG sarà False e sarà il tuo ambiente di produzione.
Ogni volta che hai bisogno di impostazioni diverse da quelle del tuo ambiente di sviluppo, usa:
if(DEBUG):
#Debug setting
else:
#Release setting