it-swarm.com.de

Django: Wie verwaltet man Entwicklungs- und Produktionseinstellungen?

Ich habe eine einfache App entwickelt. In der Bereitstellungsphase wurde klar, dass ich sowohl lokale Einstellungen als auch Produktionseinstellungen benötige.

Es wäre toll zu wissen:

  • Wie man am besten mit Entwicklungs- und Produktionseinstellungen umgehen kann. 
  • So behalten Sie Apps wie Django-Debug-Toolbar nur in einer Entwicklungsumgebung.
  • Alle anderen Tipps und bewährten Methoden für die Entwicklungs- und Bereitstellungseinstellungen.
83

Die Umgebungsvariable Django_SETTINGS_MODULE steuert, welche Einstellungsdatei Django lädt. 

Sie erstellen daher separate Konfigurationsdateien für Ihre jeweiligen Umgebungen (beachten Sie, dass sie import * natürlich aus einer separaten Datei mit gemeinsam genutzten Einstellungen) können, und verwenden Sie Django_SETTINGS_MODULE, um zu steuern, welche verwendet werden soll.

Hier ist wie:

Wie in der Django-Dokumentation erwähnt:

Der Wert von Django_SETTINGS_MODULE sollte in der Python-Pfad-Syntax sein, z. mysite.settings. Beachten Sie, dass sich das Einstellungsmodul im Suchpfad für Python-Import befinden sollte.

Nehmen wir an, Sie haben myapp/production_settings.py und myapp/test_settings.py in Ihrem Quell-Repository erstellt.

In diesem Fall müssen Sie Django_SETTINGS_MODULE=myapp.production_settings so einstellen, dass der erste Code und Django_SETTINGS_MODULE=myapp.test_settings verwendet werden.


Von jetzt an geht es darum, die Umgebungsvariable Django_SETTINGS_MODULE festzulegen. 

Einrichten von Django_SETTINGS_MODULE mithilfe eines Skripts oder einer Shell

Sie können dann ein Bootstrap-Skript oder einen Prozessmanager verwenden, um die korrekten Einstellungen zu laden (durch Festlegen der Umgebung), oder führen Sie es einfach von Ihrer Shell aus aus, bevor Sie Django starten: export Django_SETTINGS_MODULE=myapp.production_settings.

Beachten Sie, dass Sie diesen Export jederzeit von einer Shell aus ausführen können - er muss nicht in Ihrem .bashrc oder irgendetwas leben.

Django_SETTINGS_MODULE mit einem Prozessmanager einstellen

Wenn Sie nicht gern ein Bootstrap-Skript schreiben, das die Umgebung festlegt (und es gibt sehr gute Gründe, dies zu empfinden!), Würde ich empfehlen, einen Prozessmanager zu verwenden:


Beachten Sie schließlich, dass can die Variable PYTHONPATH nutzen kann, um die Einstellungen an einem völlig anderen Ort zu speichern (z. B. auf einem Produktionsserver, wobei sie in /etc/ gespeichert werden). Dies ermöglicht das Trennen der Konfiguration von Anwendungsdateien. Möglicherweise möchten Sie das nicht, es hängt davon ab, wie Ihre App strukturiert ist. 

82
Thomas Orozco

Ich habe normalerweise eine Einstellungsdatei pro Umgebung und eine gemeinsam genutzte Einstellungsdatei:

/myproject/
  settings.production.py
  settings.development.py
  shared_settings.py

Jede meiner Umgebungsdateien hat:

try:
    from shared_settings import *
except ImportError:
    pass

Dadurch kann ich ggf. freigegebene Einstellungen überschreiben (indem Sie die Modifikationen unterhalb dieser Zeilengruppe hinzufügen).

Ich wähle dann aus, welche Einstellungsdateien verwendet werden sollen, indem ich sie mit settings.py verlinke:

ln -s settings.development.py settings.py
30
Daniel Watkins

Verwenden Sie standardmäßig die Produktionseinstellungen, erstellen Sie jedoch eine Datei mit dem Namen settings_dev.py im selben Ordner wie Ihre settings.py-Datei. Fügen Sie dort Überschreibungen hinzu, z. B. DEBUG=True.

Fügen Sie auf dem Computer, der für die Entwicklung verwendet wird, Folgendes Ihrer ~/.bashrc-Datei hinzu:

export Django_DEVELOPMENT=true

Fügen Sie am Ende Ihrer settings.py-Datei Folgendes hinzu.

# Override production variables if Django_DEVELOPMENT env variable is set
if os.environ.get('Django_DEVELOPMENT') is not None:
    from settings_dev import * 

(Beachten Sie, dass das Importieren von * in Python generell vermieden werden sollte, dies ist jedoch ein eindeutiger Umstand.)

Standardmäßig überschreiben die Produktionsserver nichts. Erledigt!

Verglichen mit den anderen Antworten ist diese Antwort einfacher, da keine Aktualisierung von PYTHONPATH oder die Einstellung von Django_SETTINGS_MODULE erforderlich ist, sodass Sie jeweils nur an einem Django-Projekt arbeiten können.

30
cs01

Erstellen Sie mehrere settings*.py-Dateien und extrapolieren Sie die Variablen, die pro Umgebung geändert werden müssen. Dann am Ende Ihrer Master-settings.py-Datei:

try:
  from settings_dev import *
except ImportError:
  pass

Sie behalten die separaten settings_*-Dateien für jede Stufe.

Fügen Sie oben in Ihrer settings_dev.py-Datei Folgendes hinzu:

import sys
globals().update(vars(sys.modules['settings']))

So importieren Sie Variablen, die Sie ändern müssen.

Dieser Wiki-Eintrag enthält weitere Ideen, wie Sie Ihre Einstellungen aufteilen können.

9
Burhan Khalid

Ich verwende die fantastischen Django-Konfigurationen , und alle Einstellungen werden in meinem settings.py gespeichert:

from configurations import Configuration

class Base(Configuration):
    # all the base settings here...
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    ...

class Develop(Base):
    # development settings here...
    DEBUG = True 
    ...

class Production(Base):
    # production settings here...
    DEBUG = False

Um das Django-Projekt zu konfigurieren, bin ich einfach den docs gefolgt.

4

Hier ist der Ansatz, den wir verwenden:

  • ein settings-Modul, um Einstellungen zur besseren Lesbarkeit in mehrere Dateien aufzuteilen;
  • eine .env.json-Datei zum Speichern von Anmeldeinformationen und Parametern, die von unserem Git-Repository ausgeschlossen werden sollen oder die von der Umgebung abhängen;
  • eine env.py-Datei zum Lesen der .env.json-Datei

Betrachten Sie die folgende Struktur:

...
.env.json           # the file containing all specific credentials and parameters
.gitignore          # the .gitignore file to exclude `.env.json`
project_name/       # project dir (the one which Django-admin.py creates)
  accounts/         # project's apps
    __init__.py
    ...
  ...
  env.py            # the file to load credentials
  settings/
    __init__.py     # main settings file
    database.py     # database conf
    storage.py      # storage conf
    ...
venv                # virtualenv
...

Mit .env.json wie:

{
    "debug": false,
    "allowed_hosts": ["mydomain.com"],
    "Django_secret_key": "my_very_long_secret_key",
    "db_password": "my_db_password",
    "db_name": "my_db_name",
    "db_user": "my_db_user",
    "db_Host": "my_db_Host",
}

Und project_name/env.py:

<!-- language: lang-python -->
import json
import os


def get_credentials():
    env_file_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    with open(os.path.join(env_file_dir, '.env.json'), 'r') as f:
        creds = json.loads(f.read())
    return creds


credentials = get_credentials()

Wir können die folgenden Einstellungen haben:

<!-- language: lang-py -->
# project_name/settings/__init__.py
from project_name.env import credentials
from project_name.settings.database import *
from project_name.settings.storage import *
...

SECRET_KEY = credentials.get('Django_secret_key')

DEBUG = credentials.get('debug')

ALLOWED_HOSTS = credentials.get('allowed_hosts', [])

INSTALLED_APPS = [
    'Django.contrib.admin',
    'Django.contrib.auth',
    'Django.contrib.contenttypes',
    'Django.contrib.sessions',
    'Django.contrib.messages',
    'Django.contrib.staticfiles',

    ...
]

if DEBUG:
    INSTALLED_APPS += ['debug_toolbar']

...

# project_name/settings/database.py
from project_name.env import credentials

DATABASES = {
    'default': {
        'ENGINE': 'Django.db.backends.postgresql_psycopg2',
        'NAME': credentials.get('db_name', ''),
        'USER': credentials.get('db_user', ''),
        'Host': credentials.get('db_Host', ''),
        'PASSWORD': credentials.get('db_password', ''),
        'PORT': '5432',
    }
}

die Vorteile dieser Lösung sind:

  • benutzerspezifische Anmeldeinformationen und Konfigurationen für lokale Entwicklung, ohne das git-Repository zu ändern;
  • umgebungsspezifische Konfiguration Sie können beispielsweise drei verschiedene Umgebungen mit drei verschiedenen .env.json-Werten wie dev, Stagging und Production verwenden.
  • Anmeldeinformationen befinden sich nicht im Repository

Ich hoffe, das hilft, lassen Sie es mich wissen, wenn Sie bei dieser Lösung irgendwelche Einschränkungen sehen.

4
Charlesthk

So mache ich es in 6 einfachen Schritten:

  1. Erstellen Sie einen Ordner in Ihrem Projektverzeichnis und nennen Sie ihn settings

    Projektstruktur:

    myproject/
           myapp1/
           myapp2/              
           myproject/
                  settings/
    
  2. Erstellen Sie vier Python-Dateien im Verzeichnis settings, dh init.py, base.py, dev.py und prod.py.

    Einstellungsdateien:

    setting/
         init.py
         base.py
         prod.py
         dev.py 
    
  3. Öffnen Sie init.py und füllen Sie ihn mit folgendem Inhalt:

    init.py:

    from .base import *
    # you need to set "myproject = 'prod'" as an environment variable 
    # in your OS (on which your website is hosted)
    if os.environ['myproject'] == 'prod':                          
       from .prod import * 
    else:
       from .dev import *   
    
  4. Öffnen Sie base.py und füllen Sie es mit allen allgemeinen Einstellungen (die sowohl in der Produktion als auch in der Entwicklung verwendet werden). Beispiel:

    base.py:

    import os
    ...
    INSTALLED_APPS = [...]
    MIDDLEWARE = [...]
    TEMPLATES = [{...}]
    ...
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    MEDIA_ROOT = os.path.join(BASE_DIR, '/path/')
    MEDIA_URL = '/path/'
    
  5. Öffne dev.py und füge die Dinge ein, die entwicklungsspezifisch sind, zum Beispiel:

    dev.py:

    DEBUG = True
    ALLOWED_HOSTS = ['localhost']
    ...
    
  6. Öffne prod.py und füge das Zeug ein, das produktionsspezifisch ist, zum Beispiel:

    prod.py:

    DEBUG = False
    ALLOWED_HOSTS = ['www.example.com']
    LOGGING = [...]
    ...
    
4
Ahtisham

aufbau der Antwort von cs01:

wenn Sie Probleme mit der Umgebungsvariablen haben, setzen Sie den Wert auf eine Zeichenfolge (z. B. habe ich Django_DEVELOPMENT="true").

Ich habe auch den Datei-Workflow von cs01 wie folgt geändert:

#settings.py
import os
if os.environ.get('Django_DEVELOPMENT') is not None:
    from settings_dev import * 
else:
    from settings_production import *
#settings_dev.py
development settings go here
#settings_production.py
production settings go here

Auf diese Weise muss Django nicht die gesamte Einstellungsdatei lesen, bevor die entsprechende Einstellungsdatei ausgeführt wird. Diese Lösung ist praktisch, wenn Ihre Produktionsdatei nur Inhalte Ihres Produktionsservers benötigt.

Hinweis: In Python 3 muss für importierte Dateien ein . angehängt werden (z. B. from .settings_dev import *).

2
Brian Lee

Ich verwende die folgende Dateistruktur:

project/
   ...
   settings/
   settings/common.py
   settings/local.py
   settings/prod.py
   settings/__init__.py -> local.py

__init__.py ist also ein Link (ln in Unix oder mklink in Windows) zu local.py oder kann zu prod.py sein, sodass die Konfiguration noch im project.settings-Modul enthalten ist und sauber ist und wenn Sie eine bestimmte Konfiguration verwenden möchten, können Sie die Umgebungsvariable verwenden Django_SETTINGS_MODULE an project.settings.prod, wenn Sie einen Befehl für die Produktionsumgebung ausführen müssen.

In den Dateien prod.py und local.py:

from .shared import *

DATABASE = {
    ...
}

und die shared.py-Datei bleibt ohne spezifische Konfigurationen global.

1
Felipe Buccioni

Wenn Sie 1 Einstellungsdatei behalten möchten und Ihr Entwicklungsbetriebssystem sich von Ihrem Produktionsbetriebssystem unterscheidet, können Sie dies an der Unterseite Ihrer Einstellungen.py einfügen:

from sys import platform
if platform == "linux" or platform == "linux2":
    # linux
    # some special setting here for when I'm on my prod server
Elif platform == "darwin":
    # OS X
    # some special setting here for when I'm developing on my mac
Elif platform == "win32":
    # Windows...
    # some special setting here for when I'm developing on my pc

Lesen Sie mehr: Wie überprüfe ich das Betriebssystem in Python?

0
User

Dies scheint beantwortet worden zu sein, aber eine Methode, die ich in Kombination mit der Versionskontrolle verwende, ist folgende:

Richten Sie eine env.py-Datei in demselben Verzeichnis wie die Einstellungen in meiner lokalen Entwicklungsumgebung ein, die ich auch zu .gitignore hinzufüge:

env.py:

#!usr/bin/python

Django_ENV = True
ALLOWED_HOSTS = ['127.0.0.1', 'dev.mywebsite.com']

.gitignore:

mywebsite/env.py

einstellungen.py:

if os.path.exists(os.getcwd() + '/env.py'):
    #env.py is excluded using the .gitignore file - when moving to production we can automatically set debug mode to off:
    from env import *
else:
    Django_ENV = False

DEBUG = Django_ENV

Ich finde, dass dies funktioniert und ist viel eleganter - mit env.py können Sie leicht unsere lokalen Umgebungsvariablen sehen und wir können all das ohne mehrere settings.py-Dateien oder ähnliches verarbeiten. Diese Methode ermöglicht die Verwendung aller Arten von lokalen Umgebungsvariablen, die auf unserem Produktionsserver nicht festgelegt werden sollen. Durch die Verwendung von .gitignore über die Versionskontrolle halten wir auch alles nahtlos integriert.

0
user7179686