Django:如何管理开发和生产设置?

Kri*_*uck 107 python django

我一直在开发一个基本的应用程序.现在处于部署阶段,我很清楚我需要本地设置和生产设置.

知道以下内容会很棒:

  • 如何最好地处理开发和生产设置.
  • 如何仅在开发环境中保留django-debug-toolbar等应用程序.
  • 有关开发和部署设置的任何其他提示和最佳实践.

Tho*_*zco 94

DJANGO_SETTINGS_MODULE环境变量控制该设置文件Django会加载.

因此,您可以为各自的环境创建单独的配置文件(请注意,它们当然可以import *来自单独的"共享设置"文件),并用于DJANGO_SETTINGS_MODULE控制要使用的文件.

这是如何做:

如Django文档中所述:

DJANGO_SETTINGS_MODULE的值应该是Python路径语法,例如mysite.settings.请注意,设置模块应位于Python导入搜索路径中.

所以,让我们假设你创建myapp/production_settings.pymyapp/test_settings.py在源存储库.

在这种情况下,您将分别设置DJANGO_SETTINGS_MODULE=myapp.production_settings使用前者并DJANGO_SETTINGS_MODULE=myapp.test_settings使用后者.


从现在开始,问题归结为设置DJANGO_SETTINGS_MODULE环境变量.

设置DJANGO_SETTINGS_MODULE使用脚本或shell

然后,您可以使用引导脚本或进程管理器来加载正确的设置(通过设置环境),或者在启动Django之前从shell运行它:export DJANGO_SETTINGS_MODULE=myapp.production_settings.

请注意,您可以随时从shell运行此导出 - 它不需要存在于您.bashrc或任何内容中.

DJANGO_SETTINGS_MODULE使用Process Manager进行设置

如果你不喜欢编写一个设置环境的引导脚本(并且有很好的理由感受到这种方式!),我建议使用进程管理器:


最后,请注意,您可以利用该PYTHONPATH变量将设置存储在完全不同的位置(例如,在生产服务器上,将其存储在其中/etc/).这允许将配置与应用程序文件分开.您可能有也可能不想要,这取决于您的应用程序的结构.

  • 为了澄清,由于`settings.py`文件默认存储在`SiteName/settings.py`中,如果将备用设置文件放在同一目录中,则添加到bin/activate的行应为`DJANGO_SETTINGS_MODULE ="SiteName. test_settings"`其他优秀答案! (7认同)
  • 巧合你知道如何一步一步地做这个教程,我是Django的新手,不知道在哪里设置DJANGO_SETTINGS_MODULE或PYTHONPATH (2认同)

cs0*_*s01 40

默认情况下,使用生产设置,但创建一个与文件settings_dev.py位于同一文件夹中的settings.py文件.在那里添加覆盖,例如DEBUG=True.

在将用于开发的计算机上,将其添加到您的~/.bashrc文件中:

export DJANGO_DEVELOPMENT=true
Run Code Online (Sandbox Code Playgroud)

settings.py文件的底部,添加以下内容.

# Override production variables if DJANGO_DEVELOPMENT env variable is set
if os.environ.get('DJANGO_DEVELOPMENT') is not None:
    from settings_dev import * 
Run Code Online (Sandbox Code Playgroud)

(请注意,*Python中通常应避免导入,但这是一种独特的情况)

默认情况下,生产服务器不会覆盖任何内容.完成!

与其他答案相比,这个更简单,因为它不需要更新PYTHONPATH,或者设置DJANGO_SETTINGS_MODULE只允许您一次处理一个django项目.

  • 这怎么不是正确的答案?现在真的很乱.Ty cs01 (7认同)
  • @brt 这是一个坏主意:它会始终使用您的“DEV”设置,这会泄漏公共服务器上的私人数据。你真的只是想检查一下`DJANGO_DEVELOPMENT` 环境变量是否存在(即`is not None`)。 (4认同)
  • @ cs01我将通过删除`is not None`检查来确保它存在并且是真实的。另外os.getenv是简写 (2认同)

Dan*_*ins 33

我通常每个环境都有一个设置文件和一个共享设置文件:

/myproject/
  settings.production.py
  settings.development.py
  shared_settings.py
Run Code Online (Sandbox Code Playgroud)

我的每个环境文件都有:

try:
    from shared_settings import *
except ImportError:
    pass
Run Code Online (Sandbox Code Playgroud)

这允许我在必要时覆盖共享设置(通过在该节下面添加修改).

然后,我通过将其链接到settings.py来选择要使用的设置文件:

ln -s settings.development.py settings.py
Run Code Online (Sandbox Code Playgroud)

  • 我们没有lint我们的设置文件,因为它们不是真正的代码,因为它们是用Python表示的配置. (11认同)
  • 你如何处理pep8禁止`import*`?你禁用那张支票吗?我已经将这个导入包装在`exec()`中,但是我不能在这个文件中没有定义的变量上有条件,也不能改变`INSTALLED_APPS`变量,因为它是"未定义的" (2认同)

Aht*_*ham 11

这是我通过6个简单步骤完成的操作:

  1. 在项目目录中创建一个文件夹并命名 settings

    项目结构:

    myproject/
           myapp1/
           myapp2/              
           myproject/
                  settings/
    
    Run Code Online (Sandbox Code Playgroud)
  2. settings目录中创建四个python文件,分别__init__.pybase.pydev.pyprod.py

    设置文件:

    settings/
         __init__.py
         base.py
         prod.py
         dev.py 
    
    Run Code Online (Sandbox Code Playgroud)
  3. 打开 __init__.py并填写以下内容:

    __init__.py:

    from .base import *
    # you need to set "myproject = 'prod'" as an environment variable
    # in your OS (on which your website is hosted)
    if os.environ['myproject'] == 'prod':
       from .prod import *
    else:
       from .dev import *
    
    Run Code Online (Sandbox Code Playgroud)
  4. 打开base.py并填写所有常用设置(将在生产和开发中使用)。例如:

    base.py:

    import os
    ...
    INSTALLED_APPS = [...]
    MIDDLEWARE = [...]
    TEMPLATES = [{...}]
    ...
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    MEDIA_ROOT = os.path.join(BASE_DIR, '/path/')
    MEDIA_URL = '/path/'
    
    Run Code Online (Sandbox Code Playgroud)
  5. 打开dev.py并包含特定于开发的内容,例如:

    dev.py:

    DEBUG = True
    ALLOWED_HOSTS = ['localhost']
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  6. 打开prod.py并包括特定于生产的东西,例如:

    prod.py:

    DEBUG = False
    ALLOWED_HOSTS = ['www.example.com']
    LOGGING = [...]
    ...
    
    Run Code Online (Sandbox Code Playgroud)

  • 干净,简单,有道理,对于我这个白痴来说很容易理解。谢谢你! (4认同)
  • @cikatomo 更改 BASE_DIR 变量以使项目文件夹上一层 (2认同)

Bur*_*lid 10

创建多个settings*.py文件,外推每个环境需要更改的变量.然后在主settings.py文件的末尾:

try:
  from settings_dev import *
except ImportError:
  pass
Run Code Online (Sandbox Code Playgroud)

settings_*为每个阶段保留单独的文件.

settings_dev.py文件的顶部,添加以下内容:

import sys
globals().update(vars(sys.modules['settings']))
Run Code Online (Sandbox Code Playgroud)

要导入需要修改的变量.

wiki条目有关于如何拆分设置的更多想法.


Cha*_*thk 7

这是我们使用的方法:

  • 一个settings将设置分成多个文件以提高可读性的模块;
  • 一个.env.json文件,用于存储我们希望从git存储库中排除或特定于环境的凭据和参数;
  • 一个env.py文件来读取.env.json文件

考虑以下结构:

...
.env.json           # the file containing all specific credentials and parameters
.gitignore          # the .gitignore file to exclude `.env.json`
project_name/       # project dir (the one which django-admin.py creates)
  accounts/         # project's apps
    __init__.py
    ...
  ...
  env.py            # the file to load credentials
  settings/
    __init__.py     # main settings file
    database.py     # database conf
    storage.py      # storage conf
    ...
venv                # virtualenv
...
Run Code Online (Sandbox Code Playgroud)

.env.json喜欢:

{
    "debug": false,
    "allowed_hosts": ["mydomain.com"],
    "django_secret_key": "my_very_long_secret_key",
    "db_password": "my_db_password",
    "db_name": "my_db_name",
    "db_user": "my_db_user",
    "db_host": "my_db_host",
}
Run Code Online (Sandbox Code Playgroud)

project_name/env.py

<!-- language: lang-python -->
import json
import os


def get_credentials():
    env_file_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    with open(os.path.join(env_file_dir, '.env.json'), 'r') as f:
        creds = json.loads(f.read())
    return creds


credentials = get_credentials()
Run Code Online (Sandbox Code Playgroud)

我们可以进行以下设置:

<!-- language: lang-py -->
# project_name/settings/__init__.py
from project_name.env import credentials
from project_name.settings.database import *
from project_name.settings.storage import *
...

SECRET_KEY = credentials.get('django_secret_key')

DEBUG = credentials.get('debug')

ALLOWED_HOSTS = credentials.get('allowed_hosts', [])

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    ...
]

if DEBUG:
    INSTALLED_APPS += ['debug_toolbar']

...

# project_name/settings/database.py
from project_name.env import credentials

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': credentials.get('db_name', ''),
        'USER': credentials.get('db_user', ''),
        'HOST': credentials.get('db_host', ''),
        'PASSWORD': credentials.get('db_password', ''),
        'PORT': '5432',
    }
}
Run Code Online (Sandbox Code Playgroud)

该解决方案的好处是:

  • 用于本地开发的用户专用凭证和配置,而无需修改git存储库;
  • 针对特定环境的配置,例如,您可以具有三个不同的环境,其中包括三个不同的环境,.env.json例如dev,stagging和production;
  • 凭证不在存储库中

希望对您有所帮助,如果您对此解决方案有任何疑问,请告诉我。


小智 6

我使用了很棒的django-configuration,所有设置都存储在我的计算机中settings.py

from configurations import Configuration

class Base(Configuration):
    # all the base settings here...
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    ...

class Develop(Base):
    # development settings here...
    DEBUG = True 
    ...

class Production(Base):
    # production settings here...
    DEBUG = False
Run Code Online (Sandbox Code Playgroud)

要配置Django项目,我只需遵循docs即可


Ale*_*sha 5

用于settings.py生产。在同一目录中创建settings_dev.py覆盖。

# settings_dev.py

from .settings import * 

DEBUG = False
Run Code Online (Sandbox Code Playgroud)

在开发机器上运行您的 Django 应用程序:

DJANGO_SETTINGS_MODULE=<your_app_name>.settings_dev python3 manage.py runserver
Run Code Online (Sandbox Code Playgroud)

在产品机器上运行就像你settings.py什么都没有一样。

优点

  1. settings.py(用于生产)完全不知道是否存在任何其他环境。
  2. 要了解 prod 和 dev 之间的区别,您只需查看一个位置 - settings_dev.py。无需收集分散在settings_prod.pysettings_dev.py和中的配置settings_shared.py
  3. 如果有人在解决生产问题后向您的产品配置添加了一个设置,您可以放心,它也会出现在您的开发配置中(除非明确覆盖)。因此,不同配置文件之间的差异将被最小化。