我正在尝试在 Django 1.2 中使用local_setting,但它对我不起作用。目前我只是将 local_settings.py 添加到我的项目中。
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.
}
}
问题是 local_settings.py 不会覆盖 settings.py 。 有什么问题?
答案 0 :(得分:117)
你不能只添加local_settings.py,你必须明确地导入它。
在settings.py的结束处,添加以下内容:
try:
from local_settings import *
except ImportError:
pass
try / except块就在那里,所以当你没有实际定义local_settings文件时,Python就会忽略这种情况。
答案 1 :(得分:68)
这是我认为的最佳做法:
local_settings
从settings
local_settings
会覆盖特定于本地环境的设置,尤其是DATABASES
,SECRET_KEY
,ALLOWED_HOSTS
和DEBUG
变量--settings=local_settings
您可以像这样实施local_settings
:
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.
}
}
其他一些要点:
settings.py
处于版本控制状态,编写方式可供贡献者使用local_settings.py
(或更常见的是prod_settings.py
)不在版本控制中,并通过指定--settings=prod_settings
或类似内容在生产中使用。尽可能少地触摸股票设置文件也可以更轻松地升级您的django版本。当您将Django升级到下一个版本时,请查看库存settings.py
和您的差异,并根据更改的内容采取必要的操作。默认值的更改可能很重要,触摸原始settings.py
文件越少,就越容易识别上游更改。
答案 2 :(得分:10)
由于主题经常重新出现,让我总结一下为什么你可能想要考虑这种方法:
哑设置文件非常快速且易于更改;特别是在生产环境中。不需要python:任何白痴都可以跳入并在一个只列出名称和值的文件中更改数据库密码;特别是与一个复杂的python设置文件相比,它充满了神秘危险的BIGCAPS名称。
应用程序settings
应与应用程序code
完全分开。您可以将config.ini放在存储库根目录之外,再也不用担心repo pull会破坏您的设置,或者您的个人设置会污染回购,或者您的settings.py中的聪明代码没有让其成为其他人的优势
这不适用于小型项目,但对于较大的项目,我得出结论,local_settings策略并没有削减它;随着时间的推移,应用程序编程越来越难以处理;主要是因为设置变得衍生和/或相关。设置根据本地设置做出反应可能有很好的理由,这会强制导入local_settings
文件向settings.py
的中间爬行。我发现事情会发生变得混乱。
我目前的解决方案是使用config
文件,我将其命名为“local.ini”。它仅包含在已部署实例之间实际更改的那些值。没有代码:它们只是价值观和布尔值:
[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
有了这个,我可以将settings.py
视为任何其他应用程序代码:调整它,检入并部署它,而不必担心测试可能潜伏在local_settings python中的任何代码码。我的settings.py
没有因以后的设置取决于本地设置而出现的竞争条件,我可以打开和关闭功能,编写易于遵循的线性代码。当我忘记添加一些新值时,不再急忙调整local_settings文件,并且不再有daves_local_settings.py
和bobs_local_settings.py
个文件进入存储库。
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'
如果您遇到BOFH,就像我曾经遇到过一样,他对将local.ini
加入/etc
目录/etc/ourapp.ini
和所以请将应用程序目录本身保存为纯存储库导出。当然你可以用local_settings.py做到这一点,但他想做的最后一件事就是搞乱了python代码。一个他可以处理的简单配置文件。
答案 3 :(得分:5)
我保留了__local_settings.py
的副本:
local_settings.py
在版本控制中被忽略,但不是__local_settings.py
README.md
以告知团队如何设置:cp {__,}local_settings.py
(为其local_settings制作副本)我曾经导过这些设置。
# settings.py
DATABASE = {...}
try:
from .local_settings import *
except ImportError:
pass
我只是从local_settings.py
导入设置本身。
使用以下命令:python manage.py runserver --settings=<proj>.local_settings
。
# local_settings.py & __local_settings.py
from .settings import *
DATABASE = {...}
而且,因为我通常不会直接与manage.py
互动,因为我明确需要一些参数(例如address:port
)。因此,我将所有这些命令放入Makefile
。
例如,这是我的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
因此:
make dep
make sh
make run
如果您不使用Makefile
作为工作流程,那么您可以使用前面的方法,但如果您使用的是makefile,那么我相信更明确一点在你的Makefile中。
答案 4 :(得分:3)
在运行服务器之前执行
export DJANGO_SETTINGS_MODULE=your_app_name.local_settings
其中your_app_name应替换为您的应用程序名称。
别忘了做
from settings import *
你的local_settings.py文件中的
答案 5 :(得分:1)
另一种方法是使用python-dotenv
和环境变量来自定义不同环境的设置。
在.env
:
settings.py
文件
# .env
SECRET_KEY=your-secret-key
DATABASE_PASSWORD=your-database-password
将以下代码添加到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)
此时,.env
文件中已解析的键/值作为环境变量出现,可以通过os.getenv()
方便地访问它们:
# settings.py
import os
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')
答案 6 :(得分:0)
我找到了类似的解决方案。这是我对这种情况的配置:
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 = {
...
}
答案 7 :(得分:0)
将此添加到文件settings.py
的末尾try:
from .local_settings import *
except ImportError:
pass
并使用您的新设置创建文件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.
}
}