J'essaie d'utiliser local_setting dans Django 1.2, mais cela ne fonctionne pas pour moi. Pour le moment, j'ajoute simplement local_settings.py à mon projet.
settings.py
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'Oracle'.
'NAME': 'banco1', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'Host': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
local_settings.py
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'Oracle'.
'NAME': 'banco2', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'Host': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
Le problème est que local_settings.py ne remplace pas settings.py .
Vous ne pouvez pas simplement ajouter local_settings.py, vous devez l'importer explicitement.
A la fin de very de votre fichier settings.py, ajoutez ceci:
try:
from local_settings import *
except ImportError:
pass
Le bloc try/except est là, de sorte que Python ignore simplement le cas où vous n'avez pas défini de fichier local_settings.
C’est la meilleure pratique à mon avis:
local_settings
importe de settings
local_settings
remplace les paramètres spécifiques à l'environnement local, en particulier les variables DATABASES
, SECRET_KEY
, ALLOWED_HOSTS
et DEBUG
--settings=local_settings
Vous pouvez implémenter local_settings
comme ceci:
from settings import *
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'Oracle'.
'NAME': 'banco2', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'Host': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
Quelques points clés supplémentaires:
settings.py
est en contrôle de version, écrit de manière à être prêt à être utilisé par les contributeurslocal_settings.py
(ou plus généralement prod_settings.py
) N'EST PAS dans le contrôle de version et est utilisé en production en spécifiant --settings=prod_settings
ou similaire.Toucher le moins possible le fichier de paramètres de stock facilite également la mise à niveau de votre version de Django. Lorsque vous mettez à niveau Django vers la version suivante, examinez le diff dans le stock settings.py
et le vôtre, et prenez les mesures nécessaires en fonction de ce qui a changé. Les modifications des valeurs par défaut peuvent être importantes. Moins vous toucherez le fichier settings.py
original, plus il sera facile de discerner les modifications en amont.
Puisque le sujet refait surface régulièrement, permettez-moi de résumer pourquoi vous pourriez envisager cette approche:
un fichier de paramètres stupide est très rapide et facile à modifier; surtout dans un environnement de production. Aucun python requis: n'importe quel idiot peut intervenir et changer le mot de passe de la base de données dans un fichier qui ne contient que des noms et des valeurs; en particulier par rapport à un fichier de paramètres python complexe contenant de mystérieux noms dangereux BIGCAPS.
l'application settings
doit être complètement séparée de l'application code
. Vous pouvez placer un fichier config.ini en dehors de la racine du référentiel et ne plus jamais vous inquiéter d'un empotage entravant les réglages de vos paramètres personnels, ni de la pollution de celui-ci par le repo, ni de ce code astucieux de vos settings.py ne le rendant pas plus avantageux pour les autres .
Cela ne s'appliquera pas aux petits projets, mais sur des projets plus importants, j'ai conclu que la stratégie de configuration locale ne permettait pas de réduire les coûts. avec le temps, il y a assez de programmation d'applications qui rend difficile à gérer; principalement lorsque les paramètres deviennent dérivés et/ou codépendants. Il peut exister de bonnes raisons pour que les paramètres réagissent en fonction des paramètres locaux, ce qui oblige l’importation d’un fichier local_settings
à remonter vers le milieu de settings.py
. Je trouve que les choses commencent à devenir compliquées à mesure que cela se produit.
Ma solution actuelle consiste à utiliser un fichier config
, je l’appelle "local.ini". Il ne contient que les valeurs qui changent réellement entre les instances déployées. Il n'y a pas de code: ce ne sont que des valeurs et des booléens:
[global]
domain = 127.0.0.1:8000
database_Host = 127.0.0.1
database_name = test_database
debug = Yes
google_analytics_id = UA-DEV-1
payments = testing
use_cdn = No
Grâce à cela, je peux traiter le settings.py
comme n'importe quel autre code d'application: modifiez-le, archivez-le et déployez-le sans avoir à vous soucier de tester quel que soit le code dissimulé dans un code python local_settings. Mon settings.py
est exempt de conditions de concurrence qui se présentent lorsque les paramètres ultérieurs dépendent des paramètres locaux, et je peux activer et désactiver les fonctionnalités pour écrire du code linéaire facile à suivre. Plus besoin de modifier à la hâte le fichier local_settings lorsque j'ai oublié d'ajouter une nouvelle valeur, et plus aucun fichier daves_local_settings.py
et bobs_local_settings.py
ne se glisse dans le référentiel.
from ConfigParser import RawConfigParser
parser = RawConfigParser()
APPLICATION_ROOT = path.abspath(path.dirname(__file__))
parser.readfp(open(path.join(APPLICATION_ROOT, 'local.ini')))
# simple variables
DATABASE_Host = parser.get('global', 'database_Host')
DATABASE_NAME = parser.get('global', 'database_name')
# interdependencies
from version import get_cdn_version
CDN = 'd99phdomw5k72k.cloudfront.net'
if parser.getboolean('global', 'use_cdn'):
STATIC_URL = '/{}/static/{}/'.format(CDN, get_cdn_version())
else:
STATIC_URL = '/static/'
# switches
payments = parser.get('global', 'payments')
if payments == 'testing':
PAYMENT_GATEWAY_ENDPOINT = 'https://api.sandbox.gateway.com'
else:
PAYMENT_GATEWAY_ENDPOINT = 'https://api.live.gateway.com'
Si vous rencontrez un BOFH , comme je l'avais déjà fait une fois, il était particulièrement enthousiasmé par la possibilité de coller le local.ini
dans le répertoire /etc
en tant que /etc/ourapp.ini
et de conserver ainsi le répertoire de l'application proprement dit en tant qu'exportation de référentiel pur. Bien sûr, vous pouvez le faire avec un fichier local_settings.py mais la dernière chose qu’il souhaitait faire était de manipuler le code python. Un simple fichier de configuration qu'il pourrait manipuler.
J'ai gardé une copie de __local_settings.py
:
local_settings.py
est ignoré dans le contrôle de version, mais pas __local_settings.py
README.md
pour informer l'équipe de la configuration: cp {__,}local_settings.py
(qui en crée une copie pour leurs paramètres local_settings)J'avais l'habitude d'importer ces paramètres.
# settings.py
DATABASE = {...}
try:
from .local_settings import *
except ImportError:
pass
Je viens d'importer les paramètres à partir du local_settings.py
.
Et avec la commande suivante: python manage.py runserver --settings=<proj>.local_settings
.
# local_settings.py & __local_settings.py
from .settings import *
DATABASE = {...}
Et depuis, d'habitude, je n'interagis pas directement avec manage.py
, car certains paramètres me sont explicitement nécessaires (par exemple, address:port
). Par conséquent, je mets tous ces commandes dans ma Makefile
.
Par exemple, voici mon Makefile:
run:
python manage.py runserver 0.0.0.0:8000 --settings=<proj>.local_settings
sh:
python manage.py Shell_plus --settings=<proj>.local_settings
dep:
npm install
pip install -r requirements.txt
Ainsi:
make dep
make sh
make run
À condition que vous utilisiez non en utilisant Makefile
comme flux de travail, vous pouvez utiliser la méthode précédente, mais si vous utilisez makefile, alors je pense qu'il est préférable d'être plus explicite dans votre Makefile.
Avant d’exécuter le serveur, faites
export Django_SETTINGS_MODULE=your_app_name.local_settings
où your_app_name doit être remplacé par le nom de votre application . Et n'oublie pas de faire
from settings import *
dans votre fichier local_settings.py
Ajoutez ceci à la fin du fichier settings.py
try:
from .local_settings import *
except ImportError:
pass
Et créez le fichier local_settings.py avec vos nouveaux paramètres par exemple
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'Oracle'.
'NAME': 'banco2', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'Host': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
Une autre approche consiste à utiliser python-dotenv
et des variables d’environnement pour personnaliser les paramètres de différents environnements.
Créez le fichier .env
à côté de votre settings.py
:
# .env
SECRET_KEY=your-secret-key
DATABASE_PASSWORD=your-database-password
Ajoutez le code suivant à votre settings.py
:
# settings.py
from dotenv import load_dotenv
load_dotenv()
# OR, explicitly providing path to '.env'
from pathlib import Path # python 3.4+
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
À ce stade, les clés/valeurs analysées du fichier .env
sont présentes sous forme de variables d’environnement et sont facilement accessibles via os.getenv()
:
# settings.py
import os
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')
J'ai trouvé la solution similaire. Voici ma configuration pour ce cas:
settings.py:
DEBUG = False
try:
from local_settings import *
except ImportError:
pass
if DEBUG is False:
ALLOWED_HOSTS = ['sth.com']
DATABASES = {
....
}
local_settings.py:
from settings import *
ALLOWED_HOSTS = ['*']
DEBUG = True
DATABASES = {
...
}