Django本地设置

时间:2011-02-05 21:58:37

标签: python django settings

我正在尝试在 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 。 有什么问题?

8 个答案:

答案 0 :(得分:117)

你不能只添加local_settings.py,你必须明确地导入它。

在settings.py的结束处,添加以下内容:

try:
    from local_settings import *
except ImportError:
    pass

try / except块就在那里,所以当你没有实际定义local_settings文件时,Python就会忽略这种情况。

答案 1 :(得分:68)

这是我认为的最佳做法:

  • local_settingssettings
  • 导入
  • 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文件越少,就越容易识别上游更改。

答案 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.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目录/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.
    }
}