处理本地开发和生产服务器设置的推荐方法是什么?其中一些(如常量等)可以在两者中更改/访问,但其中一些(如静态文件的路径)需要保持不同,因此不应在每次部署新代码时都被覆盖。
目前,我将所有常量添加到 settings.py
。但是每次我在本地更改一些常量时,我都必须将其复制到生产服务器并编辑文件以进行生产特定的更改... :(
编辑:看起来这个问题没有标准答案,我接受了最流行的方法。
Two Scoops of Django: Best Practices for Django 1.5 建议对设置文件使用版本控制并将文件存储在单独的目录中:
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
base.py
文件包含常用设置(例如 MEDIA_ROOT 或 ADMIN),而 local.py
和 production.py
具有特定于站点的设置:
在基础文件 settings/base.py
中:
INSTALLED_APPS = (
# common apps...
)
在本地开发设置文件 settings/local.py
中:
from project.settings.base import *
DEBUG = True
INSTALLED_APPS += (
'debug_toolbar', # and other apps for local development
)
在文件生产设置文件 settings/production.py
中:
from project.settings.base import *
DEBUG = False
INSTALLED_APPS += (
# other apps for production site
)
然后在运行 django 时,添加 --settings
选项:
# Running django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local
# Running django shell on the production site
$ ./manage.py shell --settings=project.settings.production
这本书的作者还在 Github 上发布了 a sample project layout template。
在 settings.py
中:
try:
from local_settings import *
except ImportError as e:
pass
您可以覆盖 local_settings.py
中需要的内容;那么它应该远离您的版本控制。但是既然你提到了复制,我猜你什么都不用;)
settings_local
而不是 local_settings
,以便在按字母顺序排列的文件夹列表中将其与 settings.py
分组。使用 .gitignore
将 settings_local.py
排除在版本控制之外,因为凭据不属于 Git。想象一下意外地开源它们。我在 git 中保留了一个名为 settings_local.py.txt
的模板文件。
使用以下布局代替 settings.py
:
.
└── settings/
├── __init__.py <= not versioned
├── common.py
├── dev.py
└── prod.py
common.py
是您的大部分配置所在的位置。
prod.py
从 common 导入所有内容,并覆盖它需要覆盖的任何内容:
from __future__ import absolute_import # optional, but I like it
from .common import *
# Production overrides
DEBUG = False
#...
同样,dev.py
从 common.py
导入所有内容并覆盖它需要覆盖的任何内容。
最后,__init__.py
是您决定要加载哪些设置的位置,也是您存储机密的位置(因此不应对该文件进行版本控制):
from __future__ import absolute_import
from .prod import * # or .dev if you want dev
##### DJANGO SECRETS
SECRET_KEY = '(3gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'
##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."
我喜欢这个解决方案的地方是:
一切都在您的版本控制系统中,除了秘密 大多数配置都在一个地方:common.py。特定于产品的东西放在 prod.py 中,特定于开发的东西放在 dev.py 中。这很简单。您可以覆盖 prod.py 或 dev.py 中来自 common.py 的内容,也可以覆盖 __init__.py 中的任何内容。这是简单的python。没有重新导入黑客。
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "foobar.settings")
foobar 是一个带有 __init__.py
文件的文件夹,而 settings 是一个带有 __init__.py
文件的文件夹,其中包含我的秘密并导入 dev.py,然后导入 common.py . 编辑 没关系,我没有安装所需的模块。我的错!这很好用!!
我使用 Harper Shelby 发布的“if DEBUG”设置样式的略微修改版本。显然,根据环境(win/linux/etc.),代码可能需要稍作调整。
我过去使用“if DEBUG”,但我发现有时我需要在 DEUBG 设置为 False 的情况下进行测试。我真正想区分环境是生产还是开发,这让我可以自由选择 DEBUG 级别。
PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
PRODUCTION = True
else:
PRODUCTION = False
DEBUG = not PRODUCTION
TEMPLATE_DEBUG = DEBUG
# ...
if PRODUCTION:
DATABASE_HOST = '192.168.1.1'
else:
DATABASE_HOST = 'localhost'
我仍然认为这种设置方式正在进行中。我还没有看到任何一种方法来处理涵盖所有基础的 Django 设置,同时设置起来也不是很麻烦(我不喜欢 5x 设置文件方法)。
os.environ['COMPUTERNAME']
很遗憾,它不适用于 PythonAnywhere。你得到一个 KeyError。
我使用 settings_local.py 和 settings_production.py。在尝试了几个选项后,我发现当简单地拥有两个设置文件感觉轻松快捷时,很容易在复杂的解决方案上浪费时间。
当你为你的 Django 项目使用 mod_python/mod_wsgi 时,你需要将它指向你的设置文件。如果您将其指向本地服务器上的 app/settings_local.py 和生产服务器上的 app/settings_production.py,那么生活就会变得轻松。只需编辑适当的设置文件并重新启动服务器(Django 开发服务器将自动重新启动)。
python manage.py runserver
运行),使用哪个设置文件?
TL;DR:诀窍是在将 settings/base.py
导入任何 settings/<purpose>.py
之前修改 os.environment
,这将大大简化事情。
光是想想所有这些交织在一起的文件就让我头疼。组合、导入(有时是有条件的)、覆盖、修补已设置的内容,以防 DEBUG
设置稍后更改。什么样的恶梦!
这些年来,我经历了所有不同的解决方案。他们都有点工作,但管理起来非常痛苦。哇!我们真的需要这么多麻烦吗?我们从一个 settings.py
文件开始。现在我们需要一个文档以正确地将所有这些以正确的顺序组合在一起!
我希望我终于用下面的解决方案达到了(我的)最佳位置。
让我们回顾一下目标(一些常见的,一些我的)
保守秘密——不要将它们存储在存储库中!通过环境设置设置/读取密钥和秘密,12 因子样式。有合理的后备默认值。理想情况下,对于本地开发,除了默认值之外,您不需要其他任何东西。 …但尽量保持默认生产安全。最好在本地错过设置覆盖,而不是必须记住调整默认设置以确保生产安全。能够以影响其他设置的方式打开/关闭调试(例如,使用或不使用压缩的 javascript)。用途设置之间的切换,如本地/测试/暂存/生产,应该仅基于 DJANGO_SETTINGS_MODULE,仅此而已。 …但允许通过 DATABASE_URL 等环境设置进行进一步参数化。 …还允许他们使用不同的目的设置并在本地并排运行它们,例如。本地开发人员机器上的生产设置,以访问生产数据库或烟雾测试压缩样式表。如果未明确设置环境变量(至少需要一个空值),则失败,尤其是在生产中,例如。 EMAIL_HOST_PASSWORD。在 django-admin startproject 期间响应在 manage.py 中设置的默认 DJANGO_SETTINGS_MODULE 将条件保持在最低限度,如果条件是目的环境类型(例如,对于生产集日志文件及其轮换),则覆盖相关目的设置文件中的设置。
不要的
不要让 django 从文件中读取 DJANGO_SETTINGS_MODULE 设置。啊!想想这是多么元。如果您需要一个文件(如 docker env),在启动 django 进程之前将其读入环境。不要在您的项目/应用程序代码中覆盖 DJANGO_SETTINGS_MODULE,例如。基于主机名或进程名。如果您懒得设置环境变量(例如 setup.py 测试),请在运行项目代码之前在工具中进行设置。避免对 django 如何读取其设置进行魔术和修补,对设置进行预处理,但事后不要干预。没有基于复杂逻辑的废话。配置应该是固定的和物化的,而不是动态计算的。在这里提供一个备用默认值就足够了。你真的想调试吗,为什么在本地你有正确的设置集,但在远程服务器上的生产中,在一百台机器上,计算不同?哦!单元测试?对于设置?严重地?
解决方案
我的策略包括与 ini
样式文件一起使用的出色 django-environ,为本地开发提供 os.environment
默认值,一些最小且短的 settings/<purpose>.py
文件具有 import settings/base.py
AFTER {3 } 是从 INI
文件设置的。这有效地给了我们一种设置注入。
这里的技巧是在导入 settings/base.py
之前修改 os.environment
。
要查看完整示例,请执行 repo:https://github.com/wooyek/django-settings-strategy
.
│ manage.py
├───data
└───website
├───settings
│ │ __init__.py <-- imports local for compatibility
│ │ base.py <-- almost all the settings, reads from proces environment
│ │ local.py <-- a few modifications for local development
│ │ production.py <-- ideally is empty and everything is in base
│ │ testing.py <-- mimics production with a reasonable exeptions
│ │ .env <-- for local use, not kept in repo
│ __init__.py
│ urls.py
│ wsgi.py
设置/.env
本地开发的默认值。一个秘密文件,主要用于设置所需的环境变量。如果本地开发中不需要它们,请将它们设置为空值。我们在此处而不在 settings/base.py
中提供默认值,以在环境中丢失时在任何其他机器上失败。
设置/local.py
这里发生的是从 settings/.env
加载环境,然后从 settings/base.py
导入常用设置。之后,我们可以覆盖一些以简化本地开发。
import logging
import environ
logging.debug("Settings loading: %s" % __file__)
# This will read missing environment variables from a file
# We wan to do this before loading a base settings as they may depend on environment
environ.Env.read_env(DEBUG='True')
from .base import *
ALLOWED_HOSTS += [
'127.0.0.1',
'localhost',
'.example.com',
'vagrant',
]
# https://docs.djangoproject.com/en/1.6/topics/email/#console-backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
LOGGING['handlers']['mail_admins']['email_backend'] = 'django.core.mail.backends.dummy.EmailBackend'
# Sync task testing
# http://docs.celeryproject.org/en/2.5/configuration.html?highlight=celery_always_eager#celery-always-eager
CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
设置/生产.py
对于生产,我们不应该期望一个环境文件,但是如果我们正在测试某些东西,那么拥有一个环境文件会更容易。但无论如何,我们只提供很少的内联默认值,因此 settings/base.py
可以做出相应的响应。
environ.Env.read_env(Path(__file__) / "production.env", DEBUG='False', ASSETS_DEBUG='False')
from .base import *
这里的主要兴趣点是 DEBUG
和 ASSETS_DEBUG
覆盖,仅当它们从环境和文件中丢失时,它们才会应用于 python os.environ
。
这些将是我们的生产默认值,无需将它们放在环境或文件中,但如果需要,它们可以被覆盖。整洁的!
设置/base.py
这些是您的主要香草 django 设置,带有一些条件和大量从环境中读取它们的内容。几乎所有东西都在这里,使所有有目的的环境保持一致并尽可能相似。
主要区别如下(我希望这些是不言自明的):
import environ
# https://github.com/joke2k/django-environ
env = environ.Env()
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# Where BASE_DIR is a django source root, ROOT_DIR is a whole project root
# It may differ BASE_DIR for eg. when your django project code is in `src` folder
# This may help to separate python modules and *django apps* from other stuff
# like documentation, fixtures, docker settings
ROOT_DIR = BASE_DIR
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', default=False)
INTERNAL_IPS = [
'127.0.0.1',
]
ALLOWED_HOSTS = []
if 'ALLOWED_HOSTS' in os.environ:
hosts = os.environ['ALLOWED_HOSTS'].split(" ")
BASE_URL = "https://" + hosts[0]
for host in hosts:
host = host.strip()
if host:
ALLOWED_HOSTS.append(host)
SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
if "DATABASE_URL" in os.environ: # pragma: no cover
# Enable database config through environment
DATABASES = {
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
'default': env.db(),
}
# Make sure we use have all settings we need
# DATABASES['default']['ENGINE'] = 'django.contrib.gis.db.backends.postgis'
DATABASES['default']['TEST'] = {'NAME': os.environ.get("DATABASE_TEST_NAME", None)}
DATABASES['default']['OPTIONS'] = {
'options': '-c search_path=gis,public,pg_catalog',
'sslmode': 'require',
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
# 'ENGINE': 'django.contrib.gis.db.backends.spatialite',
'NAME': os.path.join(ROOT_DIR, 'data', 'db.dev.sqlite3'),
'TEST': {
'NAME': os.path.join(ROOT_DIR, 'data', 'db.test.sqlite3'),
}
}
}
STATIC_ROOT = os.path.join(ROOT_DIR, 'static')
# django-assets
# http://django-assets.readthedocs.org/en/latest/settings.html
ASSETS_LOAD_PATH = STATIC_ROOT
ASSETS_ROOT = os.path.join(ROOT_DIR, 'assets', "compressed")
ASSETS_DEBUG = env('ASSETS_DEBUG', default=DEBUG) # Disable when testing compressed file in DEBUG mode
if ASSETS_DEBUG:
ASSETS_URL = STATIC_URL
ASSETS_MANIFEST = "json:{}".format(os.path.join(ASSETS_ROOT, "manifest.json"))
else:
ASSETS_URL = STATIC_URL + "assets/compressed/"
ASSETS_MANIFEST = "json:{}".format(os.path.join(STATIC_ROOT, 'assets', "compressed", "manifest.json"))
ASSETS_AUTO_BUILD = ASSETS_DEBUG
ASSETS_MODULES = ('website.assets',)
最后一点显示了这里的力量。 ASSETS_DEBUG
有一个合理的默认值,它可以在 settings/production.py
中被覆盖,甚至可以被环境设置覆盖!耶!
实际上,我们有一个混合的重要性等级:
settings/.py - 根据目的设置默认值,不存储秘密 settings/base.py - 主要由环境进程环境设置控制 - 12 因子宝贝! settings/.env - 易于启动的本地默认值
我在 django-split-settings 的帮助下管理我的配置。
它是默认设置的直接替代品。它很简单,但可配置。并且不需要重构您的现有设置。
这是一个小例子(文件 example/settings/__init__.py
):
from split_settings.tools import optional, include
import os
if os.environ['DJANGO_SETTINGS_MODULE'] == 'example.settings':
include(
'components/default.py',
'components/database.py',
# This file may be missing:
optional('local_settings.py'),
scope=globals()
)
而已。
更新
我写了一篇关于使用 django-split-sttings
管理 django
设置的 blog post。看一看!
请记住,settings.py 是一个实时代码文件。假设您没有在生产环境中设置 DEBUG(这是最佳实践),您可以执行以下操作:
if DEBUG:
STATIC_PATH = /path/to/dev/files
else:
STATIC_PATH = /path/to/production/files
非常基本,但理论上,您可以仅根据 DEBUG 的值或您想要使用的任何其他变量或代码检查来达到任何复杂程度。
大多数这些解决方案的问题在于,您要么在常用设置之前应用本地设置,要么在它们之后应用本地设置。
所以不可能覆盖像
特定于 env 的设置定义了 memcached 池的地址,在主设置文件中,该值用于配置缓存后端
特定于环境的设置将应用程序/中间件添加或删除到默认设置
同时。
一种解决方案可以使用带有 ConfigParser 类的“ini”样式的配置文件来实现。它支持多个文件、惰性字符串插值、默认值和许多其他好东西。一旦加载了多个文件,就可以加载更多文件,并且它们的值将覆盖以前的文件(如果有)。
您加载一个或多个配置文件,具体取决于机器地址、环境变量甚至之前加载的配置文件中的值。然后,您只需使用解析的值来填充设置。
我成功使用的一种策略是:
加载默认的 defaults.ini 文件
检查机器名称,并加载与反向 FQDN 匹配的所有文件,从最短匹配到最长匹配(所以,我加载了 net.ini,然后是 net.domain.ini,然后是 net.domain.webserver01.ini,每一个可能覆盖以前的值)。这个账号也是开发者的机器,所以每个人都可以设置自己喜欢的数据库驱动等进行本地开发
检查是否声明了“集群名称”,在这种情况下加载 cluster.cluster_name.ini,它可以定义数据库和缓存 IP 等内容
作为您可以通过此实现的示例,您可以为每个环境定义一个“子域”值,然后在默认设置(如 hostname: %(subdomain).whatever.net
)中使用它来定义 django 需要工作的所有必要的主机名和 cookie .
这是我能得到的 DRY,大多数(现有)文件只有 3 或 4 个设置。除此之外,我必须管理客户配置,因此存在一组额外的配置文件(包括数据库名称、用户和密码、分配的子域等),每个客户一个或多个。
可以根据需要将其缩放到最低或最高,您只需在配置文件中放入要为每个环境配置的键,一旦需要新配置,将先前的值放入默认配置中,然后覆盖它在必要时。
该系统已被证明是可靠的,并且可以很好地与版本控制配合使用。长期以来,它一直用于管理两个独立的应用程序集群(每台机器 15 个或更多 django 站点的独立实例),拥有 50 多个客户,其中集群的大小和成员根据系统管理员的心情而变化。 .
config = ConfigParser.ConfigParser()
加载解析器,然后读取文件 config.read(array_of_filenames)
并使用 config.get(section, option)
获取值。所以首先你加载你的配置,然后你用它来读取设置的值。
我也在与 Laravel 合作,我喜欢那里的实现。我试图模仿它并将其与 T. Stone 提出的解决方案相结合(见上图):
PRODUCTION_SERVERS = ['*.webfaction.com','*.whatever.com',]
def check_env():
for item in PRODUCTION_SERVERS:
match = re.match(r"(^." + item + "$)", socket.gethostname())
if match:
return True
if check_env():
PRODUCTION = True
else:
PRODUCTION = False
DEBUG = not PRODUCTION
也许这样的事情会帮助你。
我对这个问题的解决方案也是这里已经说明的一些解决方案的混合:
我保留了一个名为 local_settings.py 的文件,该文件在 dev 中具有 USING_LOCAL = True 的内容,在 prod 中具有 USING_LOCAL = False 的内容
在 settings.py 我对该文件进行导入以获取 USING_LOCAL 设置
然后,我将所有与环境相关的设置都基于该设置:
DEBUG = USING_LOCAL
if USING_LOCAL:
# dev database settings
else:
# prod database settings
我更喜欢拥有两个需要维护的单独的 settings.py 文件,因为与将它们分布在多个文件中相比,我可以更容易地将我的设置结构化在一个文件中。像这样,当我更新设置时,我不会忘记为两种环境都这样做。
当然,每种方法都有其缺点,这个也不例外。这里的问题是,每当我将更改推送到生产环境时,我都无法覆盖 local_settings.py
文件,这意味着我不能盲目地复制所有文件,但这是我可以忍受的。
对于我的大多数项目,我使用以下模式:
创建 settings_base.py 我存储所有环境通用的设置每当我需要使用具有特定要求的新环境时,我都会创建新的设置文件(例如 settings_local.py),它继承 settings_base.py 的内容并覆盖/添加适当的设置变量(来自 settings_base 导入 *)
(要使用自定义设置文件运行 manage.py,您只需使用 --settings 命令选项:manage.py <command> --settings=settings_you_wish_to_use.py
)
1 - 在您的应用程序中创建一个新文件夹并为其命名设置。
2 - 现在在其中创建一个新的 __init__.py
文件并在其中写入
from .base import *
try:
from .local import *
except:
pass
try:
from .production import *
except:
pass
- 在设置文件夹名称 local.py
和 production.py
和 base.py
中创建三个新文件。
4 - 在 base.py
中,复制之前 settings.py
文件夹的所有内容并用不同的名称重命名,比如 old_settings.py
。
5 - 在 base.py 中更改您的 BASE_DIR 路径以指向您的新设置路径
旧路径-> BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
新路径 -> BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
这样,项目目录可以结构化,并且可以在生产和本地开发之间进行管理。
我使用了上面提到的 jpartogi 的变体,我发现它更短一些:
import platform
from django.core.management import execute_manager
computername = platform.node()
try:
settings = __import__(computername + '_settings')
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file '%r_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % (computername, __file__))
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings)
基本上在每台计算机(开发或生产)上,我都有适当的 hostname_settings.py 文件,可以动态加载。
还有 Django 经典设置。我个人是它的忠实粉丝。它是由 Django IRC 上最活跃的人之一构建的。您将使用环境变量来设置内容。
http://django-classy-settings.readthedocs.io/en/latest/
为了在不同的环境中使用不同的 settings
配置,请创建不同的设置文件。在您的部署脚本中,使用 --settings=<my-settings.py>
参数启动服务器,通过它您可以在不同的环境中使用不同的设置。
使用这种方法的好处:
您的设置将根据每个环境模块化您可以导入包含基本配置的 master_settings.py 环境中的 environmnet_configuration.py 并覆盖您要在该环境中更改的值。如果您拥有庞大的团队,每个开发人员都可能拥有自己的 local_settings.py,他们可以将其添加到代码存储库中,而不会有任何修改服务器配置的风险。如果您使用 git,则可以将这些本地设置添加到 .gitnore;如果您使用 Mercurial 进行版本控制(或任何其他),则可以将这些本地设置添加到 .hginore。这样,本地设置甚至不会成为保持其清洁的实际代码库的一部分。
我的设置拆分如下
settings/
|
|- base.py
|- dev.py
|- prod.py
我们有 3 个环境
开发者
分期
生产
现在显然分期和生产应该有尽可能多的相似环境。所以我们为两者保留了 prod.py
。
但是有一种情况,我必须确定正在运行的服务器是生产服务器。 @T。 Stone 的回答帮助我写了如下检查。
from socket import gethostname, gethostbyname
PROD_HOSTS = ["webserver1", "webserver2"]
DEBUG = False
ALLOWED_HOSTS = [gethostname(), gethostbyname(gethostname()),]
if any(host in PROD_HOSTS for host in ALLOWED_HOSTS):
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
我在 manage.py 中区分它并创建了两个单独的设置文件:local_settings.py 和 prod_settings.py。
在 manage.py 我检查服务器是本地服务器还是生产服务器。如果它是本地服务器,它将加载 local_settings.py,而它是生产服务器,它将加载 prod_settings.py。基本上这就是它的样子:
#!/usr/bin/env python
import sys
import socket
from django.core.management import execute_manager
ipaddress = socket.gethostbyname( socket.gethostname() )
if ipaddress == '127.0.0.1':
try:
import local_settings # Assumed to be in the same directory.
settings = local_settings
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'local_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
else:
try:
import prod_settings # Assumed to be in the same directory.
settings = prod_settings
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'prod_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file prod_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings)
我发现将设置文件分成两个单独的文件比在设置文件中执行大量 if 更容易。
如果您愿意,作为维护不同文件的替代方法:如果您使用 git 或任何其他 VCS 将代码从本地推送到服务器,您可以做的是将设置文件添加到 .gitignore。
这将允许您在两个地方拥有不同的内容而不会出现任何问题。所以在服务器上你可以配置一个独立版本的 settings.py 并且在本地所做的任何更改都不会反映在服务器上,反之亦然。
此外,它还会从 github 中删除 settings.py 文件,这是我看到很多新手都在做的大错。
我认为@T 建议了最好的解决方案。 Stone,但我不知道为什么不在 Django 中使用 DEBUG 标志。我为我的网站编写以下代码:
if DEBUG:
from .local_settings import *
简单的解决方案总是比复杂的解决方案好。
我发现这里的回答很有帮助。 (这个问题是否得到了更明确的解决?最后一个回复是一年前。)在考虑了所有列出的方法之后,我想出了一个我没有在此处列出的解决方案。
我的标准是:
一切都应该在源代码管理中。我不喜欢乱七八糟的东西。
理想情况下,将设置保存在一个文件中。如果我看的不正,我会忘记事情:)
无需手动编辑部署。应该能够使用单个结构命令进行测试/推送/部署。
避免将开发设置泄漏到生产中。
尽可能接近“标准”(*cough*) Django 布局。
我认为打开主机是有道理的,但后来发现这里的真正问题是针对不同环境的不同设置,并且有一个 aha 时刻。我将此代码放在我的 settings.py 文件的末尾:
try:
os.environ['DJANGO_DEVELOPMENT_SERVER'] # throws error if unset
DEBUG = True
TEMPLATE_DEBUG = True
# This is naive but possible. Could also redeclare full app set to control ordering.
# Note that it requires a list rather than the generated tuple.
INSTALLED_APPS.extend([
'debug_toolbar',
'django_nose',
])
# Production database settings, alternate static/media paths, etc...
except KeyError:
print 'DJANGO_DEVELOPMENT_SERVER environment var not set; using production settings'
这样,应用程序默认为生产设置,这意味着您明确地将您的开发环境“列入白名单”。忘记在本地设置环境变量比忘记在生产环境中设置某些东西并使用一些开发设置要安全得多。
在本地开发时,无论是从 shell 还是在 .bash_profile 或任何地方:
$ export DJANGO_DEVELOPMENT_SERVER=yep
(或者,如果您在 Windows 上进行开发,请通过控制面板或这些天所谓的任何东西进行设置……Windows 总是让它变得如此晦涩,以至于您可以设置环境变量。)
使用这种方法,开发设置都在一个(标准)位置,并在需要时简单地覆盖生产设置。任何与开发设置有关的乱七八糟的事情都应该完全安全地提交源代码控制,而不影响生产。
DJANGO_SETTINGS_MODULE
envvar,而不是每次都使用--settings
。这适用于例如 Heroku:将其全局设置为生产环境,然后在您的 .env 文件中使用 dev 覆盖它。DJANGO_SETTINGS_MODULE
env var 是最好的主意,谢谢 Simon。BASE_DIR
设置更改为os.path.dirname(os.path.realpath(os.path.dirname(__file__) + "/.."))
from django.conf import settings
这是一个抽象接口并将代码与设置位置解耦的对象,docs.djangoproject.com/en/dev/topics/settings/…