Wie konfigurieren Sie Django für die einfache Entwicklung und Bereitstellung?

112

Ich neige dazu, SQLite bei der Django- Entwicklung zu verwenden, aber auf einem Live-Server wird häufig etwas Robusteres benötigt ( z. B. MySQL / PostgreSQL ). Ausnahmslos müssen auch andere Änderungen an den Django-Einstellungen vorgenommen werden: unterschiedliche Protokollierungsorte / -intensitäten, Medienpfade usw.

Wie verwalten Sie all diese Änderungen, um die Bereitstellung zu einem einfachen, automatisierten Prozess zu machen?

Peter Mortensen
quelle
Ich mache anscheinend nichts so ausgefallenes wie alle anderen :). Ich nutze einfach das ORM, das Django liefert.
Andrew Sledge
1
Die Frage war, wie man das Ändern von Einstellungen automatisiert, um zwischen Umgebungen zu wechseln :-)
Guruprasad
Sie können sich dieses Paket ansehen
sobolevn

Antworten:

86

Update: Django-Konfigurationen wurden veröffentlicht, was für die meisten Leute wahrscheinlich eine bessere Option ist als manuell.

Wenn Sie es vorziehen, Dinge manuell zu erledigen, gilt meine frühere Antwort immer noch:

Ich habe mehrere Einstellungsdateien.

  • settings_local.py - Hostspezifische Konfiguration wie Datenbankname, Dateipfade usw.
  • settings_development.py- Konfiguration für die Entwicklung, z DEBUG = True.
  • settings_production.py- Konfiguration für die Produktion, z SERVER_EMAIL.

Ich verbinde diese alle mit einer settings.pyDatei, die zuerst importiert wird settings_local.py, und dann mit einer der beiden anderen. Es entscheidet durch zwei Einstellungen im Inneren, welche geladen werden sollen settings_local.py- DEVELOPMENT_HOSTSund PRODUCTION_HOSTS. settings.pyruft platform.node()auf, um den Hostnamen des Computers zu ermitteln, auf dem er ausgeführt wird, sucht dann in den Listen nach diesem Hostnamen und lädt die zweite Einstellungsdatei, je nachdem, in welcher Liste der Hostname gefunden wird.

Auf diese Weise müssen Sie sich nur wirklich darum kümmern, die settings_local.pyDatei mit der hostspezifischen Konfiguration auf dem neuesten Stand zu halten, und alles andere wird automatisch erledigt.

Schauen Sie sich hier ein Beispiel an .

Jim
quelle
2
Was ist, wenn sich Staging (Entwicklung) und Produktion auf derselben Maschine befinden? platform.node () gibt dann dasselbe zurück.
Gwaramadze
2
Beispiellink ist ausgefallen.
Jickson
Tolle Idee, die Einstellungen anhand von Hostlisten zu ermitteln! Mein einziger Trottel ist die Nomenklatur (settings_local.py wird immer zuerst importiert, damit alle Einstellungen, die nicht überschrieben werden, tatsächlich in der Produktion aktiv sind, was das Suffix _localziemlich verwirrend macht) und die Tatsache, dass Sie keine Module verwenden (Einstellungen /base.py, settings / local.py, settings / Production.py). Es wäre auch ratsam, dies in einem separaten Repository zu speichern ... noch besser, einem sicheren Dienst, der diese Informationen aus einer kanonischen Quelle bereitstellt (wahrscheinlich für die meisten übertrieben) ... damit für einen neuen Host keine neue Version erforderlich ist.
DylanYoung
Noch besser ist es, wenn Sie eine Maschinenverwaltungssoftware verwenden, anstatt .pydie Hostliste in der Datei zu überprüfen und damit jedem Host Zugriff auf Informationen zur Konfiguration jedes anderen Hosts zu gewähren, können Sie die Datei "manage.py" mit Vorlagen versehen, um die entsprechenden Einstellungen zu verwenden Datei in Ihren Bereitstellungskonfigurationen.
DylanYoung
26

Persönlich verwende ich eine einzelne settings.py für das Projekt. Ich habe nur den Hostnamen nachgeschlagen, auf dem es sich befindet (meine Entwicklungsmaschinen haben Hostnamen, die mit "gabriel" beginnen, also habe ich nur Folgendes:

import socket
if socket.gethostname().startswith('gabriel'):
    LIVEHOST = False
else: 
    LIVEHOST = True

dann habe ich in anderen Teilen Dinge wie:

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/'

und so weiter. Ein bisschen weniger lesbar, aber es funktioniert gut und erspart das Jonglieren mehrerer Einstellungsdateien.

Gabriel Ross
quelle
Ich mag diese Idee, aber ich kann nicht zwischen verschiedenen Django-Instanzen unterscheiden, die auf demselben Host ausgeführt werden. Dies würde beispielsweise passieren, wenn auf demselben Host unterschiedliche Instanzen für unterschiedliche Subdomänen ausgeführt würden.
Erik
24

Am Ende von settings.py habe ich folgendes:

try:
    from settings_local import *
except ImportError:
    pass

Auf diese Weise muss ich, wenn ich die Standardeinstellungen überschreiben möchte, settings_local.py direkt neben settings.py einfügen.

Dmitry Shevchenko
quelle
4
Dies ist etwas gefährlich, denn wenn ein Tippfehler settings_localzu einem führt ImportError, exceptwird dieser lautlos verschluckt.
Chris Martin
Sie könnten die Nachricht No module named...vs überprüfen cannot import name..., aber es ist spröde. Oder setzen Sie Ihre Importe in settings_local.py in try-Blöcken und lösen Sie eine spezifischere Ausnahme aus: MisconfiguredSettingsoder etwas in diesem Sinne.
DylanYoung
11

Ich habe zwei Dateien. settings_base.pydie allgemeine / Standardeinstellungen enthält und in der Quellcodeverwaltung eingecheckt ist. Jede Bereitstellung verfügt über eine separate Bereitstellung settings.py, die from settings_base import *zu Beginn ausgeführt und bei Bedarf überschrieben wird.

John Millikin
quelle
1
Ich benutze das auch. Es ist dem Inversen überlegen (dmishe "from settings_local import *" am Ende von settings.py), da die lokalen Einstellungen bei Bedarf auf die globalen Einstellungen zugreifen und diese ändern können.
Carl Meyer
3
In settings_local.pydiesem Fall from settings import *können Werte in überschrieben werden settings.py. (Die settings_local.pyDatei muss am Ende von importiert werden settings.py).
Seth
Das kann sowieso gemacht werden. Schauen Sie sich oben stackackflow.com/a/7047633/3124256 an . @ Seth Das ist ein Rezept für einen zirkulären Import.
DylanYoung
7

Der einfachste Weg, den ich gefunden habe, war:

1) Verwenden Sie die Standardeinstellung settings.py für die lokale Entwicklung und 2) erstellen Sie eineproduktionseinstellungen.py, beginnend mit:

import os
from settings import *

Und dann überschreiben Sie einfach die Einstellungen, die sich in der Produktion unterscheiden:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}
Andre Bossard
quelle
2

In Bezug auf die Bereitstellung von Django selbst mit mehreren Datenbanken sollten Sie sich Djangostack ansehen . Sie können ein völlig kostenloses Installationsprogramm herunterladen, mit dem Sie Apache, Python, Django usw. installieren können. Im Rahmen des Installationsprozesses können Sie auswählen, welche Datenbank Sie verwenden möchten (MySQL, SQLite, PostgreSQL). Wir verwenden die Installationsprogramme häufig, wenn wir Bereitstellungen intern automatisieren (sie können im unbeaufsichtigten Modus ausgeführt werden).

Josue
quelle
1
Alternativ möchte ich Django Turnkey Linux empfehlen, das auf einem Ubuntu * NIX-Stack mit vorinstalliertem Django basiert.
jochem
1

Ich habe meine settings.py-Datei in einem externen Verzeichnis. Auf diese Weise wird es nicht in die Quellcodeverwaltung eingecheckt oder von einer Bereitstellung überschrieben. Ich habe dies zusammen mit den Standardeinstellungen in die Datei settings.py unter meinem Django-Projekt eingefügt:

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")

Hinweis: Dies ist sehr gefährlich, wenn Sie local_settings.py nicht vertrauen können.

Chase Seibert
quelle
1

Zusätzlich zu den von Jim erwähnten Dateien mit mehreren Einstellungen füge ich normalerweise zwei Einstellungen in meine Datei settings.py oben ein BASE_DIRund BASE_URLsetze den Pfad des Codes und die URL zur Basis der Site. Alle anderen Einstellungen werden geändert sich diesen anhängen.

BASE_DIR = "/home/sean/myapp/" z.B MEDIA_ROOT = "%smedia/" % BASEDIR

Wenn ich das Projekt verschiebe, muss ich nur diese Einstellungen bearbeiten und nicht die gesamte Datei durchsuchen.

Ich würde auch empfehlen, sich Fabric und Capistrano (Ruby-Tool, aber es kann zum Bereitstellen von Django-Anwendungen verwendet werden) anzusehen, die die Automatisierung der Remote-Bereitstellung erleichtern.

Sean O Donnell
quelle
Ansible ist Python und bietet wesentlich robustere Bereitstellungsfunktionen als Fabric. Sie passen auch gut zusammen.
DylanYoung
1

Nun, ich benutze diese Konfiguration:

Am Ende von settings.py:

#settings.py
try:
    from locale_settings import *
except ImportError:
    pass

Und 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
Sacabuche
quelle
1

So viele komplizierte Antworten!

Jede settings.py-Datei enthält:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Ich benutze dieses Verzeichnis, um die DEBUG-Variable wie folgt festzulegen (ersetzen Sie sie durch das Verzeichnis, in dem sich Ihr Entwicklungscode befindet):

DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
    DEBUG = True

Jedes Mal, wenn die Datei settings.py verschoben wird, ist DEBUG False und Ihre Produktionsumgebung.

Jedes Mal, wenn Sie andere Einstellungen als die in Ihrer Entwicklungsumgebung benötigen, verwenden Sie einfach:

if(DEBUG):
    #Debug setting
else:
    #Release setting
JM Desrosiers
quelle
0

Ich denke, es hängt von der Größe der Site ab, ob Sie SQLite nicht mehr verwenden müssen. Ich habe SQLite erfolgreich auf mehreren kleineren Live-Sites verwendet und es läuft großartig.

Ycros
quelle
0

Ich benutze die Umgebung:

if os.environ.get('WEB_MODE', None) == 'production' :
   from settings_production import *
else :
   from settings_dev import *

Ich glaube, dies ist ein viel besserer Ansatz, da Sie möglicherweise spezielle Einstellungen für Ihre Testumgebung benötigen und diese problemlos zu dieser Bedingung hinzufügen können.

Slashmili
quelle
0

Dies ist ein älterer Beitrag, aber ich denke, wenn ich diesen nützlichen hinzufüge library, wird es die Dinge vereinfachen.

Verwenden Sie die Django-Konfiguration

Schnellstart

pip install django-configurations

Unterklassifizieren Sie dann die enthaltenen Konfigurationen.Konfigurationsklasse in den Einstellungen Ihres Projekts.py oder einem anderen Modul, das Sie zum Speichern der Einstellungskonstanten verwenden, z.

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

Setzen Sie die DJANGO_CONFIGURATIONUmgebungsvariable auf den Namen der Klasse, die Sie gerade erstellt haben, z. B ~/.bashrc.:

export DJANGO_CONFIGURATION=Dev

und die DJANGO_SETTINGS_MODULEUmgebungsvariable zum Modulimportpfad wie gewohnt, z. B. in bash:

export DJANGO_SETTINGS_MODULE=mysite.settings

Alternativ können Sie die --configurationOption angeben, wenn Sie Django-Verwaltungsbefehle gemäß der Standardbefehlszeilenoption von Django verwenden --settings, z.

python manage.py runserver --settings=mysite.settings --configuration=Dev

So aktivieren Sie Django Ihre Konfiguration zu verwenden , haben Sie jetzt Ihre ändern manage.py oder wsgi.py django-Konfigurationen zu verwenden Versionen der entsprechenden Starterfunktionen, zB ein typisches Skript manage.py mit django-Konfigurationen würde wie folgt aussehen:

#!/usr/bin/env python

import os
import sys

if __name__ == "__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)

Beachten Sie, dass wir in Zeile 10 nicht das allgemeine Tool verwenden, django.core.management.execute_from_command_linesondern stattdessen configurations.management.execute_from_command_line.

Gleiches gilt für Ihre Datei wsgi.py , z.

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

Hier verwenden wir nicht die Standardfunktion django.core.wsgi.get_wsgi_application, sondern configurations.wsgi.get_wsgi_application.

Das ist es! Sie können Ihr Projekt jetzt mit manage.py und Ihrem bevorzugten WSGI-fähigen Server verwenden.

Kleiner Phild
quelle
-2

In der Tat sollten Sie wahrscheinlich in Betracht ziehen, dieselben (oder fast dieselben) Konfigurationen für Ihre Entwicklungs- und Produktionsumgebung zu verwenden. Andernfalls treten von Zeit zu Zeit Situationen wie "Hey, es funktioniert auf meinem Computer" auf.

Verwenden Sie Docker, um Ihre Bereitstellung zu automatisieren und diese WOMM-Probleme zu beseitigen .

Dmitrii Mikhailov
quelle