【问题标题】:How to properly runserver on different settings for Django?如何在 Django 的不同设置上正确运行服务器?
【发布时间】:2018-08-20 11:43:06
【问题描述】:

我有一个基本的 django rest API。出于组织目的,我想将我的一些设置分开用于 dev 和 prod。我也只是在学习分离环境。我已经阅读了一些内容,但我似乎无法让它按照我想要的方式工作。

层次结构如下所示:

- djangorest
  - api
    - __init__.py
    - models.py
    - views.py
    - urls.py
    - etc..
  - djangorest
    - __init__.py
    - settings.py
    - urls.py
    - wsgi.py

现在,当我运行服务器时,我做了一个简单的操作:

python3 manage.py runserver

该命令从 settings.py 读取设置并适当地运行它,但我查看了如何将设置分离到 prod 和 dev 中,但它不能正常工作。

我希望能够拥有:

commonsettings.py
dev.py
prod.py

在 commonsettings 中,它只会包含 dev 和 prod 中的任何内容。我试过跑步:

python3 manage.py runserver --settings=settings.dev

但它给了我一个错误,说没有名为“设置”的模块。

请帮忙。谢谢!

【问题讨论】:

  • 改用python3 manage.py runserver --settings=djangorest.dev
  • djangorest.settings.dev,如果设置文件位于设置目录中。

标签: python django


【解决方案1】:

例如我在开发设置中打开 SQL 日志

  1. 我的文件结构:
    创建设置文件夹和 mv 原始 settings.py 到 settings/defaults.py

  2. init.py

  3. 中加载默认值
# proj/proj/settings/__init__.py

from .defaults import *
  1. 编辑 dev.py
# proj/proj/settings/dev.py

from .defaults import *
DEBUG = True

# print sql to the console
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        }
    },
}

  1. 在 python 环境中运行
./manage.py runserver --settings proj.settings.dev

Django 2.1.7 |麦克

【讨论】:

  • init.py 中导入的目的是什么?
  • 将文件夹设置为模块
【解决方案2】:

创建一个名为 config 的文件夹

config/
    commonsettings.py
    dev.py
    prod.py

确保在 dev.py 和 prod.py 中从 commonsettings.py 导入所有内容,如下所示:

from .commonsettings import * 

那么如果你想运行 dev.py 设置:

python manage.py runserver --settings=config.dev

如果你想运行 prod.py:

python manage.py runserver --settings=config.prod

注意:

为了更易读的文件,许多开发人员将他们的设置文件称为:local.py(用于本地设置)production.py(用于生产设置)和 base.py(两者的通用设置)

我个人将我的设置文件放在:

config/
    settings/
        base.py
        local.py
        production.py
        test.py (For tests)

【讨论】:

  • 不需要init.py文件吗?
【解决方案3】:

此解决方案无需额外参数即可工作,并且无需跨环境替换/删除文件。

让 settings.py 决定加载哪个文件

假设您的 Django 项目名为 MyDjangoApp。

在 Django 项目的根目录中创建 config/ 目录,并为每个环境创建一个 .py 文件,例如像这样:

config/
  local.py
  dev.py
  prod.py
MyDjangoApp/
  settings.py

环境的数量没有逻辑上的限制,我只是添加了我通常拥有的三个。

然后,在MyDjangoApp/settings.py 中,我们可以添加逻辑来选择要加载的设置文件。

"""
Django settings for MyDjangoApp project.
"""

import os

# Begin: Custom per-env settings
import socket
# Use the appropriate logic to understand "where" we're running
HOST = socket.gethostname() 
configs = {
    'localhost': 'local', # replace 'localhost' with whatever your machine name is
    'dev.mysite.com': 'dev',
    'www.mysite.com': 'production',
}

config = 'config.{}'.format(configs[HOST])

settings_module = __import__(config, globals(), locals(), ['MyDjangoApp', ])

try:
    for setting in dir(settings_module):
        # Only fully-uppercase variables are supposed to be settings
        if setting == setting.upper():
            locals()[setting] = getattr(settings_module, setting)
except Exception:
    # you may ignore this exception, the print() is for debugging purposes 
    print(Exception)

# End: Custom per-env settings

# ... the rest of the common settings go here

请注意:此逻辑根据运行 Django 应用程序的服务器的 主机名 选择要加载的设置文件。这只是一个示例 - 您可以实现任何其他适合您的逻辑。

只改变需要的东西

好消息是,settings.py 仍然可以保存您的绝大多数设置,config/ 中的文件只需要包含在您的环境中更改的设置,例如:

  • 数据库
  • 调试
  • 管理员
  • 日志记录

避免在命令行中使用--settings

您可以将 Django 设置设置为 shell 环境变量,如下所示:

export DJANGO_SETTINGS_MODULE=MyDjangoApp.settings

执行此操作的最佳位置是在.sh 文件中;通常我会在 Django 项目的根目录中创建一个名为 env.sh 的文件,并在激活 virtualenv 后运行它(一次)。

文件 /env.sh 内容

#!/usr/bin/env bash

export DJANGO_SETTINGS_MODULE=MyDjangoApp.settings

要从终端(Bash,或 Windows 上的 git-scm Bash)运行它:

. env.sh 

那么无论你身在何处都可以使用./manage.py runserver启动Django服务器。

参考:https://code.djangoproject.com/wiki/SplitSettings#DevelopmentMachineDependantSettingsConfiguration

【讨论】:

    【解决方案4】:

    将所有常用配置放在 commonsettings.py 文件中。

    settings目录下的__init__.py文件中添加以下内容

    from commonsettings import *
    

    这使得 commonsettings 文件中的每个配置都可用于设置文件夹中的所有其他文件

    启动你的服务器
    python3 manage.py runserver --settings=djangorest.settings.dev
    

    【讨论】:

      【解决方案5】:

      项目层次结构将是

      - djangorest
        - api
          - __init__.py
          - models.py
          - views.py
          - urls.py
          - etc..
        - djangorest
          - settings           (folder)
          - commonsettings.py
          - dev.py
          - prod.py
          - __init__.py
          - settings.py
          - urls.py
          - wsgi.py
      

      After This 在 python manage.py runserver

      之前运行以下命令

      导出 PYTHONPATH=$PWD

      导出 DJANGO_SETTINGS_MODULE=djangorest.settings.dev

      最后python manage.py runserver

      【讨论】:

        【解决方案6】:

        在开发服务器上用 dev.py 替换 settings.py,在生产服务器上用 prod.py 替换。

        现在在 init.py 文件中编写代码

        try:
            print("Trying import production.py settings...")
            from .prod import *
        except ImportError:
            print("Trying import development.py settings...")
            from .dev import *
        

        它在生产服务器中找到 prod.py 并导入它。在开发服务器上找不到和 prod.py 并导入 dev.py

        那么你在运行runserver命令时不需要指定配置文件名。

        【讨论】:

          【解决方案7】:

          我一直在做的是在本地环境中创建一个名为 local_settings.py 的文件,该文件可以拥有自己的数据库设置、静态路径等,并在设置文件的末尾包含此

          try:
              from local_settings import *#
          except:
              pass
          

          所以在服务器上,我总是确保不导入 local_settings 并将两者很好地分开。

          【讨论】:

            猜你喜欢
            • 2021-08-22
            • 1970-01-01
            • 2012-02-10
            • 2011-01-09
            • 2019-05-02
            • 2021-07-01
            • 2021-05-10
            • 2019-03-04
            • 2023-01-24
            相关资源
            最近更新 更多