【问题标题】:Best way to handle different configuration/settings based on environment in Django project在 Django 项目中根据环境处理不同配置/设置的最佳方法
【发布时间】:2017-03-23 20:21:00
【问题描述】:

DEBUG == False 是否应该意味着应用正在生产环境中运行?

至少,这是我偶尔看到的on the internet。但是那我在settings.py 中输入什么呢?好的,我可以将本地设置放到 settings_local.py 并从 settings.py 导入。但是,如果某些设置取决于环境,那么我必须将它们放在 import 语句之后。越想越不喜欢。你呢?

【问题讨论】:

    标签: python django development-environment production-environment


    【解决方案1】:

    作为问题的答案:

    DEBUG == False 是否应该意味着应用正在生产环境中运行?

    DEBUG 是您在setting.py 文件中定义的配置。

    • 如果设置为True,如果出现未处理的异常,它会显示完整的堆栈跟踪以及所有已声明变量的值。

    • 如果设置为False,您的服务器将只返回500 状态码,而没有任何堆栈跟踪。

    在生产中,您必须将 DEBUG 设置为 False 以防止潜在的安全漏洞风险以及您不希望用户知道的其他信息。


    为了在不同的环境下使用不同的settings配置,创建不同的设置文件。并在您的部署脚本中,使用--settings=<my-settings.py> 参数启动服务器,通过该参数您可以在不同的环境中使用不同的设置

    使用这种方法的好处

    1. 您的设置将根据每个环境进行模块化

    2. 您可以在environmnet_configuration.py 中导入包含基本配置的master_settings.py,并覆盖您要在该环境中更改的值。

    3. 如果您拥有庞大的团队,每个开发人员可能都有自己的local_settings.py,他们可以将其添加到代码存储库中,而无需修改服务器配置。如果您使用 git.hginore 如果您使用 Mercurial 进行代码版本控制,则可以将这些本地设置添加到 .gitnore。这样一来,本地设置甚至不会成为保持其干净的实际代码库的一部分。

    【讨论】:

    • 我认为设置不会有太大的不同,所以我正在考虑添加DJANGO_ENV环境变量,并在settings.py中使用它来确定它是哪个环境。
    • 您可以根据DJANGO_ENV 进行操作,但更简洁的方式是我提到的方式。如果设置差别不大,请在your_environment_settings.py 中导入production_settings.py 并覆盖您想要的配置。这样,您的代码将是模块化的,并且您在本地机器上工作时不会有修改生产配置的风险。 + 如果您在大型团队中工作,每个开发人员都可以拥有唯一的文件,他们可以将其添加到 .gitinore.hginore 文件(您使用的基于提交管理器)。他们可以在本地环境中使用它
    • 但是将--settings 传递给每个django-admin 的命令有点……罗嗦。然后我是否应该将./manage.py 放入存储库并在每个环境中手动创建它?或者甚至创建manage.sh#/usr/bin/env bash\nDJANGO_SETTINGS_MODULE=<app>.settings django-admin "$@".在旁注中,我不会称第 2 点和第 3 点优势。他们更像是如何按照你的建议生活。您可以在回答中提到的另一个好处是您不太可能弄乱生产设置。
    • ...或者if [ -e <app>/local_settings.py ]; then D...=<app>.local_settings django-admin "$@"; else D...=<app>.settings django-admin "$@"
    • 我设法想出了一个script 来简化使用您的方法。请考虑将其合并到您的答案中。或者随意批评。
    【解决方案2】:

    使用django-configurations定义一些替代配置,并在每台运行代码的机器上设置环境变量DJANGO_CONFIGURATION来选择一个。

    您可以随意定义类,但我建议定义一个 Common 类,所有内容都从该类继承,然后是 DevTestProd 类。

    任何涉及系统配置的东西都应该从环境变量中提取出来(例如数据库连接、缓存连接等)。

    玩得开心!

    【讨论】:

    • 我认为django-configurations 做得过火了。考虑系统配置,能否详细说明?究竟应该从环境变量中提取什么?任何涉及密码的东西?例如,将数据库密码保留在 settings.py 之外肯定是一件好事(至少在将 settings.py 添加到存储库时)。但我认为,将数据库用户留在那里是可以的。也就是说,我现在正在考虑在settings.py 中保留尽可能多的生产设置。并覆盖/添加 local_settings.py 中的其余部分,这些部分不会添加到存储库中。你推荐django-dotenv吗?
    • 任何特定于给定机器的东西都应该在环境中。所以数据库名称、主机、端口等不应该在代码中固定,你当然可以在那里提供默认值,并且永远不要在环境中覆盖它们。从环境中读取是内置在django-configurations 中的,除非您需要,否则不需要django-dotenv
    • 但是使用环境变量覆盖值和创建local_settings.py文件有什么区别?
    • 1.一些生产环境只允许你设置(和改变)环境变量,而不是在你的包中间添加一个新文件。尽量靠近生产环境运行就好 2. 可以处理和验证环境变量 3. 我个人不喜欢在开发机器上自定义代码,单一的代码库和配置会限制生产和开发之间的差异。跨度>
    • “处理和验证环境变量”是什么意思?
    【解决方案3】:

    要添加到@anonymous 答案,这是我想出的脚本 (manage.sh):

    #!/usr/bin/env bash
    DIR=$(dirname -- "$(readlink -f -- "$0")")
    export PYTHONPATH="$DIR${PYTHONPATH:+:$PYTHONPATH}"
    if [ -e <app>/local_settings.py ]; then
        export DJANGO_SETTINGS_MODULE=<app>.local_settings
    else
        export DJANGO_SETTINGS_MODULE=<app>.settings
    fi
    django-admin "$@"
    

    如果存在,它使用&lt;app&gt;.local_settings。否则它会退回到&lt;app&gt;.settings

    或者,您可以只编辑您的manage.py

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2015-03-23
      • 2014-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多