J'ai développé une application de base. Maintenant, au stade du déploiement, il est devenu évident que j’ai besoin de paramètres locaux et de paramètres de production.
Il serait bon de savoir ce qui suit:
La Django_SETTINGS_MODULE
variable d'environnement } __ contrôle le fichier de paramètres que Django chargera.
Vous créez donc des fichiers de configuration distincts pour vos environnements respectifs (notez qu'ils peuvent bien sûr à la fois import *
à partir d'un fichier "paramètres partagés" séparé) et utilisez Django_SETTINGS_MODULE
pour contrôler lequel utiliser.
Voici comment:
Comme indiqué dans la documentation Django:
La valeur de Django_SETTINGS_MODULE doit être dans la syntaxe du chemin Python, par exemple. mysite.settings. Notez que le module de paramètres doit être sur le chemin de recherche d'importation Python.
Supposons donc que vous avez créé myapp/production_settings.py
et myapp/test_settings.py
dans votre référentiel source.
Dans ce cas, vous définissez respectivement Django_SETTINGS_MODULE=myapp.production_settings
pour utiliser l'ancien et Django_SETTINGS_MODULE=myapp.test_settings
pour utiliser le dernier.
A partir de là, le problème se résume à définir la variable d'environnement Django_SETTINGS_MODULE
.
Django_SETTINGS_MODULE
à l'aide d'un script ou d'un shellVous pouvez ensuite utiliser un script d'amorçage ou un gestionnaire de processus pour charger les paramètres corrects (en définissant l'environnement), ou simplement l'exécuter à partir de votre shell avant de démarrer Django: export Django_SETTINGS_MODULE=myapp.production_settings
.
Notez que vous pouvez exécuter cet export à tout moment à partir d'un shell - il n'a pas besoin de résider dans votre .bashrc
ni quoi que ce soit.
Django_SETTINGS_MODULE
à l'aide d'un gestionnaire de processusSi vous n'aimez pas écrire un script de démarrage qui définit l'environnement (et qu'il y a de très bonnes raisons de vous sentir ainsi!), Je vous recommande d'utiliser un gestionnaire de processus:
environment
..env
) .Enfin, notez que vous pouvez tirer parti de la variable PYTHONPATH
pour stocker les paramètres dans un emplacement complètement différent (par exemple sur un serveur de production, en les stockant dans /etc/
). Cela permet de séparer la configuration des fichiers d'application. Vous pouvez ou non vouloir cela, cela dépend de la structure de votre application.
J'ai généralement un fichier de paramètres par environnement et un fichier de paramètres partagé:
/myproject/
settings.production.py
settings.development.py
shared_settings.py
Chacun de mes fichiers d’environnement a:
try:
from shared_settings import *
except ImportError:
pass
Cela me permet de remplacer les paramètres partagés si nécessaire (en ajoutant les modifications sous cette strophe).
Je sélectionne ensuite les fichiers de paramètres à utiliser en le liant à settings.py:
ln -s settings.development.py settings.py
Par défaut, utilisez les paramètres de production, mais créez un fichier appelé settings_dev.py
dans le même dossier que votre fichier settings.py
. Ajouter remplace ici, tel que DEBUG=True
.
Ajoutez ceci à votre fichier ~/.bashrc
sur l'ordinateur qui sera utilisé pour le développement:
export Django_DEVELOPMENT=true
Au bas de votre fichier settings.py
, ajoutez ce qui suit.
# Override production variables if Django_DEVELOPMENT env variable is set
if os.environ.get('Django_DEVELOPMENT') is not None:
from settings_dev import *
(Notez que l'importation *
devrait généralement être évitée en Python, mais il s'agit d'une circonstance unique.)
Par défaut, les serveurs de production ne remplaceront rien. Terminé!
Comparée aux autres réponses, celle-ci est plus simple car elle ne nécessite pas de mettre à jour PYTHONPATH
, ni de régler Django_SETTINGS_MODULE
qui ne vous permet de travailler que sur un projet Django à la fois.
Créez plusieurs fichiers settings*.py
, en extrapolant les variables devant être modifiées par environnement. Puis à la fin de votre fichier settings.py
maître:
try:
from settings_dev import *
except ImportError:
pass
Vous conservez les fichiers settings_*
séparés pour chaque étape.
En haut de votre fichier settings_dev.py
, ajoutez ceci:
import sys
globals().update(vars(sys.modules['settings']))
Pour importer des variables que vous devez modifier.
Cette entrée wiki a plus d’idées sur la manière de diviser vos paramètres.
J'utilise awesome Django-configurations , et tous les paramètres sont stockés dans mon settings.py
:
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
Pour configurer le projet Django, je viens de suivre les docs .
Voici l'approche que nous utilisons:
settings
pour fractionner les paramètres en plusieurs fichiers pour en améliorer la lisibilité;.env.json
pour stocker les informations d'identification et les paramètres que nous voulons exclure de notre référentiel git ou qui sont spécifiques à l'environnement;env.py
pour lire le fichier .env.json
...
.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
...
.env.json
comme:{
"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",
}
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()
<!-- 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',
}
}
.env.json
différents, tels que dev, staging et production;J'espère que cela aide, faites le moi savoir si vous voyez des mises en garde avec cette solution.
Voici comment je le fais en 6 étapes faciles:
Créez un dossier dans votre répertoire de projet et nommez-le settings
.
structure du projet:
myproject/
myapp1/
myapp2/
myproject/
settings/
Créez quatre fichiers python dans le répertoire settings
, à savoir init.py
, base.py
, dev.py
et prod.py
fichiers de paramètres:
setting/
init.py
base.py
prod.py
dev.py
Ouvrez init.py
et remplissez-le avec le contenu suivant:
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 *
Ouvrez base.py
et remplissez-le avec tous les paramètres courants (qui seront utilisés à la fois en production et en développement.), Par exemple:
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/'
Ouvrez dev.py
et incluez ce qui est spécifique au développement, par exemple:
dev.py:
DEBUG = True
ALLOWED_HOSTS = ['localhost']
...
Ouvrez prod.py
et incluez ce qui est spécifique à la production, par exemple:
prod.py:
DEBUG = False
ALLOWED_HOSTS = ['www.example.com']
LOGGING = [...]
...
construire sur la réponse de cs01:
si vous rencontrez des problèmes avec la variable d'environnement, définissez sa valeur sur une chaîne (par exemple, je l'ai Django_DEVELOPMENT="true"
).
J'ai également modifié le workflow de fichiers de cs01 comme suit:
#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
De cette façon, Django n'a pas besoin de lire l'intégralité d'un fichier de paramètres avant d'exécuter le fichier de paramètres approprié. Cette solution est pratique si votre fichier de production nécessite des éléments uniquement sur votre serveur de production.
Remarque: en Python 3, les fichiers importés doivent porter un .
(par exemple from .settings_dev import *
).
J'utilise la structure de fichier suivante:
project/
...
settings/
settings/common.py
settings/local.py
settings/prod.py
settings/__init__.py -> local.py
Donc __init__.py
est un lien (ln sous unix ou mklink sous windows) avec local.py
ou peut être avec prod.py
de sorte que la configuration est toujours dans le module project.settings
est propre et organisé, et si vous voulez utiliser une configuration particulière, vous pouvez utiliser la variable d'environnement Django_SETTINGS_MODULE
à project.settings.prod
si vous devez exécuter une commande pour l'environnement de production.
Dans les fichiers prod.py
et local.py
:
from .shared import *
DATABASE = {
...
}
et le fichier shared.py
reste global sans configuration spécifique.
Si vous souhaitez conserver 1 fichier de paramètres et que votre système d'exploitation de développement est différent de votre système d'exploitation de production, vous pouvez le placer au bas de votre fichier settings.py:
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
En savoir plus: Comment puis-je vérifier le système d'exploitation en Python?
Cela semble avoir été répondu, cependant une méthode que j'utilise en combinaison avec le contrôle de version est la suivante:
Configurez un fichier env.py dans le même répertoire que les paramètres de mon environnement de développement local que j’ajoute également à .gitignore:
env.py:
#!usr/bin/python
Django_ENV = True
ALLOWED_HOSTS = ['127.0.0.1', 'dev.mywebsite.com']
.gitignore:
mywebsite/env.py
settings.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
Je trouve que cela fonctionne et est beaucoup plus élégant - avec env.py, il est facile de voir nos variables d’environnement locales et nous pouvons gérer tout cela sans plusieurs fichiers settings.py ou autres. Cette méthode permet d’utiliser toutes sortes de variables d’environnement locales que nous ne voudrions pas définir sur notre serveur de production. En utilisant le .gitignore via le contrôle de version, nous gardons également tout intégré en toute transparence.