Django 本地设置

我尝试在 姜戈1.2中使用 local _ set,但它对我不起作用。目前,我只是添加 Local _ sets. 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 _ sets. 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不覆盖 设置。 怎么了?

74774 次浏览

不能只添加 local _ setings.py,必须显式地导入它。

在设置的 结束了处. py,添加以下内容:

try:
from local_settings import *
except ImportError:
pass

这里存在 try/腰块,这样当您没有实际定义 local _ sets 文件时,Python 就会忽略这种情况。

这是我认为的最佳实践:

  • settings进口
  • local_settings覆盖特定于本地环境的设置,特别是 DATABASESSECRET_KEYALLOWED_HOSTSDEBUG变量
  • 传递给 django 管理命令标志 --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文件,就越容易识别上游更改。

由于这个话题经常重新浮出水面,让我总结一下为什么你可能想要考虑这种方法:

  • 哑设置文件非常快速且易于更改; 特别是在生产环境中。不需要 Python: 任何白痴都可以跳进去,在一个只列出名称和值的文件中更改数据库密码; 尤其是与充满神秘危险的 BIGCAPS 名称的复杂 Python 设置文件相比。

  • 应用程序 settings应该与应用程序 code完全分离。你可以把 config.ini 放在存储库根目录之外,再也不用担心回购拖动会破坏你的设置,或者你的个人设置会污染回购,或者你的 setings.py 中的聪明代码不会让它成为对其他人有利的回购。

这并不适用于小型项目,但是对于大型项目,我得出结论,本地设置策略无法解决这个问题; 随着时间的推移,足够多的应用程序编程渗透进来,变得难以处理; 主要是因为设置变得派生和/或相互依赖。设置可以根据本地设置作出反应,这些本地设置迫使导入的 local_settings文件向 settings.py的中间缓慢上升。我发现事情开始变得一团糟。

My current solution is to use a config file, I dub it "local.ini". It holds only those values which do actually change between deployed instances. There is no code: they are just values and booleans:

[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 _ sets python 代码中可能潜藏的任何代码进行测试。我的 settings.py是免费的竞争条件时,出现后来的设置取决于本地设置,我可以切换功能的开关编写易于遵循的线性代码。当我忘记添加一些新值时,不再匆忙地调整 local _ sets 文件,也不再有 daves_local_settings.pybobs_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/ourapp.ini粘贴到 /etc目录中,从而保持应用程序目录本身是一个纯粹的存储库导出的能力感到特别兴奋。当然,您可以使用 local _ setings.py 来实现这一点,但是他最不想做的事情就是搞乱 Python 代码。他可以处理的简单配置文件。

在运行服务器之前做

Export DJANGO _ SETTING _ MODULE = your _ app _ name. local _ sets 其中,您的 _ App _ name 应该被应用程序的名称替换。 别忘了

from settings import *

在您的 local _ setings.py 文件中

I kept a copy of __local_settings.py:

  • 版本控制中忽略的是 local_settings.py,而不是 __local_settings.py
  • 更新 README.md,通知团队如何设置: cp {__,}local_settings.py(为他们的 local _ setup 制作一个副本)

在过去

我曾经导入过这些设置。

# 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中。

For example, here's my 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 中更加明确。

我找到了类似的解决方案,这是我在这个案例中的配置:

设置:

DEBUG = False


try:
from local_settings import *


except ImportError:
pass


if DEBUG is False:
ALLOWED_HOSTS = ['sth.com']
DATABASES = {
....
}

Local _ sets. py:

from settings import *
ALLOWED_HOSTS = ['*']
DEBUG = True
DATABASES = {
...
}

还有一种方法是使用 python-dotenv和环境变量为不同的环境定制设置。

Create the .env file along-side your 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')

将此添加到文件 setings.py 的末尾

try:
from .local_settings import *
except ImportError:
pass

例如,使用新设置创建文件 local _ setings.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.
}
}