【问题标题】:How can I tell whether my Django application is running on development server or not?如何判断我的 Django 应用程序是否在开发服务器上运行?
【发布时间】:2010-11-20 11:25:58
【问题描述】:

如何确定我的应用程序是否在开发服务器上运行?我想我可以检查settings.DEBUG 的值并假设DEBUGTrue 那么它在开发服务器上运行,但我更愿意确定而不是依赖约定。

【问题讨论】:

    标签: python django wsgi


    【解决方案1】:

    我在 settings.py 中加入了以下内容,以区分标准开发服务器和生产服务器:

    import sys
    RUNNING_DEVSERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver')
    

    不过,这也依赖于约定。

    (根据 Daniel Magnusson 的评论修改)

    【讨论】:

    • 我必须在 prod 服务器上添加 if len(sys.argv) >1: 才能使其正常工作。
    • 这是更好的答案,因为它不需要请求。我想这样做有条件地连接媒体网址
    • 你能解释一下这是干什么用的吗?也许我不明白这个问题,但是这个变量存储了站点是否用manage.py runserver调用,对吗?你用这个做什么?我偶然发现了这篇文章,这似乎是我想学习的新东西。我正在寻找一种方法来检测我是否在本地主机上,在这种情况下打开调试(我不是在这篇文章中寻找关于这个的答案)
    • @aless80 在使用开发服务器运行时,您可能希望禁用某些特定于 uwsgi 的东西,例如 spooler
    • 在这里简化:stackoverflow.com/a/37880897
    【解决方案2】:
    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 的模块的类,但我希望这能涵盖您。

    顺便说一句,我通过在开发服务器上运行时制作了一个语法无效的模板来发现这一点,并在 TracebackRequest information 部分搜索有趣的东西,所以我只是编辑我的答案来证实符合 Nate 的想法。

    【讨论】:

    • +1 用于实际尝试解决问题,即检测哪个服务器正在为 Django 应用程序提供服务,而不是依赖于设置。例如,除了开发 Web 服务器之外,没有什么可以阻止某人在 DEBUG 模式下运行。
    • 非常酷,但我想在启动时执行一次,而不是在每次请求时执行此操作。这可能吗?
    • @TalWeiss 您可以将逻辑添加到 manage.pywsgi.py (或者保持 DRY,将逻辑添加到第三个文件中,例如 setvars.py 被两者导入和调用)。因此,请使用上述答案或其中另一个答案的逻辑,以便调用os.environ.setdefault('DJANGO_SETTINGS_MODULE','some.settings.module') 的不同变体。这假设您按环境将设置模块分成子模块。再三考虑,上面的答案在那里不起作用,因为尚未设置请求。但你明白了。
    • 在 OS X 上运行的 Django 1.5.5 中,模块名称为 wsgiref.util。所以这个 sn-p 不起作用。
    • 在linux上的Django 1.8.12中,模块名也是wsgiref.util
    【解决方案3】:

    通常这是有效的:

    import sys
    
    if 'runserver' in sys.argv:
        # you use runserver
    

    【讨论】:

    • 生产环境下会怎样?这是否意味着运行 ./manage.py runserver 而不是例如 ./manage.py shell_plus
    • 根据文档,您不应在生产环境中使用“runserver”。只要确保正确使用 DEBUG;例如添加安全网和检查。
    【解决方案4】:

    通常我会设置一个名为environment 的变量并将其设置为“开发”、“暂存”或“生产”。然后,我可以在设置文件中添加基本逻辑,以根据环境更改正在使用的设置。

    编辑:此外,您可以简单地使用此逻辑来包含覆盖基本设置的不同settings.py 文件。例如:

    if environment == "DEBUG":
        from debugsettings import *
    

    【讨论】:

      【解决方案5】:

      依赖 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 上服务的人,检查文件路径比使用环境变量要容易得多。

      【讨论】:

      • 好吧,除了我可能会在开发和生产中采用相同的路径约定(这会打败这个)的情况之外,这对我来说似乎是最好的。并为WhereTheHellIsThisServedException +1 :-)
      【解决方案6】:

      我刚才遇到了这个问题,最后写了一个类似于 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=settings python [myscript] --in-development

      只要确保你传递的额外参数不会与任何 django 冲突(实际上我使用我的应用程序名称作为参数的一部分)。 我认为这是相当不错的,因为它让我可以准确控制我的服务器和脚本何时作为 prod 或 dev 运行,而且我不依赖任何其他人的约定,除了我自己的约定。

      编辑:如果您传递无法识别的选项,manage.py 会抱怨,因此您需要将 settings.py 中的代码更改为类似

      if sys.argv[0] == 'manage.py' or '--in-development' in sys.argv:
          # ...
          pass
      

      虽然这可行,但我承认它不是最优雅的解决方案...

      【讨论】:

        【解决方案7】:

        如果您想根据运行时环境自动切换设置文件 您可以只使用环境中不同的东西,例如

        from os import environ
        if environ.get('_', ''): 
            print "This is dev - not Apache mod_wsgi"         
        

        【讨论】:

          【解决方案8】:

          您可以确定您是在WSGI(mod_wsgi、gunicorn、waitress 等)还是manage.py(运行服务器、测试、迁移等)下运行,还是在其他任何条件下运行:

          import sys
          WSGI = 'django.core.wsgi' in sys.modules
          

          【讨论】:

            【解决方案9】:

            settings.DEBUG 可以是 True 并且在 Apache 或其他一些非开发服务器下运行。它仍然会运行。据我所知,在运行时环境中除了检查 pid 并与操作系统中的 pid 进行比较之外,没有什么可以为您提供此信息。

            【讨论】:

              【解决方案10】:

              我用:

              DEV_SERVERS = [
                  'mymachine.local',
              ]
              
              DEVELOPMENT = platform.node() in DEV_SERVERS
              

              这需要注意.node() 在您的机器上返回的内容。重要的是默认设置为非开发,这样您就不会意外暴露敏感的开发信息。

              您也可以查看more complicated ways of uniquely identifying computers

              【讨论】:

                【解决方案11】:

                开发和部署环境之间的一个区别是运行它的服务器。究竟有什么不同取决于您的开发和部署环境。

                了解您自己的开发和部署环境后,HTTP 请求变量可用于区分两者。看看request variables 就像request.META.HTTP_HOSTrequest.META.SERVER_NAMErequest.META.SERVER_PORT 并在两个环境中比较它们。

                我敢打赌,您会发现一些非常明显的不同之处,可用于检测您的开发环境。在settings.py 中进行测试并设置一个您可以在其他地方使用的变量。

                【讨论】:

                  【解决方案12】:

                  受 Aryeh 回答的启发,我为自己设计的技巧就是在 sys.argv[0] 中查找我的管理脚本的名称:

                  USING_DEV_SERVER = "pulpdist/manage_site.py" in sys.argv[0]
                  

                  (我的用例是在运行测试服务器时自动启用 Django 本地身份验证 - 在 Apache 下运行时,即使在开发服务器上,我当前项目的所有身份验证都是通过 Kerberos 处理的)

                  【讨论】:

                    【解决方案13】:

                    你可以检查request.META["SERVER_SOFTWARE"]值:

                    dev_servers = ["WSGIServer", "Werkzeug"]
                    if any(server in request.META["SERVER_SOFTWARE"] for server in dev_servers):
                        print("is local")
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-19
                      • 2013-06-15
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-09-14
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多