如何确定我的应用程序是否在开发服务器上运行?我想我可以检查值settings.DEBUG
并假设它DEBUG
是否True
在开发服务器上运行,但我更愿意确定而不是依赖约定。
13 回答
我将以下内容放在我的 settings.py 中以区分标准开发服务器和生产服务器:
import sys
RUNNING_DEVSERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver')
然而,这也依赖于约定。
(根据 Daniel Magnusson 的评论进行了修改)
server = request.META.get('wsgi.file_wrapper', None)
if server is not None and server.__module__ == 'django.core.servers.basehttp':
print('inside dev')
当然,wsgi.file_wrapper
可能会在 META 上设置,并且django.core.servers.basehttp
在另一个服务器环境中具有一个极其巧合命名的模块中的类,但我希望这能涵盖您。
Traceback
顺便说一句,我通过在开发服务器上运行时制作了一个语法上无效的模板来发现这一点,并在和部分搜索有趣的东西Request information
,所以我只是在编辑我的答案以证实 Nate 的想法。
通常这有效:
import sys
if 'runserver' in sys.argv:
# you use runserver
通常我设置一个名为的变量environment
并将其设置为“DEVELOPMENT”、“STAGING”或“PRODUCTION”。在设置文件中,我可以添加基本逻辑以根据环境更改正在使用的设置。
编辑:此外,您可以简单地使用此逻辑来包含settings.py
覆盖基本设置的不同文件。例如:
if environment == "DEBUG":
from debugsettings import *
依靠 settings.DEBUG 是 AFAICS 最优雅的方式,因为它有时也用于 Django 代码库。
我想您真正想要的是一种自动设置该标志的方法,而无需每次将项目上传到生产服务器时手动更新它。
为此,我检查了 settings.py 的路径(在 settings.py 中)以确定项目在哪个服务器上运行:
if __file__ == "path to settings.py in my development machine":
DEBUG = True
elif __file__ in [paths of production servers]:
DEBUG = False
else:
raise WhereTheHellIsThisServedException()
请注意,您可能还更喜欢按照@Soviut 的建议对环境变量进行此检查。但是作为在 Windows 上开发并在 Linux 上服务的人,检查文件路径比使用环境变量要容易得多。
我刚才遇到了这个问题,最后写了一个类似于 Aryeh Leib Taurog 的解决方案。我的主要区别是,我想在运行服务器时区分生产环境和开发环境,而且在为我的应用程序运行一些一次性脚本时(我像 DJANGO_SETTINGS_MODULE=settings python [the script] 一样运行)。在这种情况下,仅查看是否 argv[1] == runserver 是不够的。所以我想出的是在我运行开发服务器时传递一个额外的命令行参数,当我运行我的脚本时,只需在 settings.py 中查找该参数。所以代码看起来像这样:
if '--in-development' in sys.argv:
## YES! we're in dev
pass
else:
## Nope, this is prod
pass
然后,运行 django 服务器就变成了
python manage.py runserver [任何你想要的选项] --in-development
运行我的脚本就像
DJANGO_SETTINGS_MODULE=设置 python [myscript] --in-development
只需确保您传递的额外参数不会与任何 django 冲突(实际上我使用我的应用程序名称作为参数的一部分)。我认为这是相当不错的,因为它让我可以准确地控制我的服务器和脚本何时作为 prod 或 dev 运行,而且我不依赖任何其他人的约定,除了我自己的约定。
编辑:如果您传递无法识别的选项,manage.py 会抱怨,因此您需要将 settings.py 中的代码更改为类似
if sys.argv[0] == 'manage.py' or '--in-development' in sys.argv:
# ...
pass
虽然这可行,但我认识到这不是最优雅的解决方案......
如果您想根据运行时环境自动切换设置文件,您可以只使用环境中不同的东西,例如
from os import environ
if environ.get('_', ''):
print "This is dev - not Apache mod_wsgi"
您可以确定您是在WSGI
(mod_wsgi, gunicorn, waitress, etc.)manage.py
还是 (runserver, test, migrate, etc.) 或其他任何东西下运行:
import sys
WSGI = 'django.core.wsgi' in sys.modules
settings.DEBUG 可以是 True 并且在 Apache 或其他一些非开发服务器下运行。它仍然会运行。据我所知,在运行时环境中除了检查 pid 并与操作系统中的 pid 进行比较之外,没有什么可以为您提供此信息。
我用:
DEV_SERVERS = [
'mymachine.local',
]
DEVELOPMENT = platform.node() in DEV_SERVERS
这需要注意.node()
机器上返回的内容。重要的是默认设置为非开发,这样您就不会意外暴露敏感的开发信息。
您还可以研究更复杂的唯一标识计算机的方法。
开发环境和部署环境之间的一个区别在于运行它的服务器。究竟有什么不同取决于您的开发和部署环境。
了解您自己的开发和部署环境后,可以使用 HTTP 请求变量来区分两者。查看请求变量,如request.META.HTTP_HOST
,request.META.SERVER_NAME
并request.META.SERVER_PORT
在两个环境中比较它们。
我敢打赌,您会发现一些非常明显的不同之处,可用于检测您的开发环境。进行测试settings.py
并设置一个可以在其他地方使用的变量。
受 Aryeh 回答的启发,我为自己设计的技巧是在以下位置查找我的管理脚本的名称sys.argv[0]
:
USING_DEV_SERVER = "pulpdist/manage_site.py" in sys.argv[0]
(我的用例是在运行测试服务器时自动启用 Django 本地身份验证 - 在 Apache 下运行时,即使在开发服务器上,我当前项目的所有身份验证都是通过 Kerberos 处理的)
您可以检查request.META["SERVER_SOFTWARE"]
值:
dev_servers = ["WSGIServer", "Werkzeug"]
if any(server in request.META["SERVER_SOFTWARE"] for server in dev_servers):
print("is local")