【问题标题】:Django + mod_wsgi. Set OS environment variable from Apache's SetEnvDjango + mod_wsgi。从 Apache 的 SetEnv 设置操作系统环境变量
【发布时间】:2015-01-14 18:31:01
【问题描述】:

我需要拆分 Django 的开发和生产设置。我决定如果设置了USKOVTASK_PROD 变量,那么应用程序应该使用生产设置。我阅读了this 的文章并尝试这样做。

我的sn-ps:

/etc/apache2/sites-enabled/uskovtask.conf:

<VirtualHost *:80>

ServerName uskovtask.*.com
ServerAlias uskovtask.*.com
DocumentRoot /mnt/ebs/uskovtask


Alias /static /mnt/ebs/uskovtask/static/
<Directory /mnt/ebs/uskovtask/static>
    Require all granted
</Directory>

#WSGIPythonPath /mnt/ebs/uskovtask
WSGIDaemonProcess uskovtask.*.com python-path=/mnt/ebs/uskovtask:/usr/lib/python2.7/site-packages
WSGIProcessGroup uskovtask.*.com
WSGIScriptAlias / /mnt/ebs/uskovtask/uskovtask/wsgi.py
SetEnv USKOVTASK_PROD 1


<Directory /mnt/ebs/uskovtask/uskovtask>
<Files wsgi.py>
    Require all granted
</Files>
</Directory>

</VirtualHost>

wsgi.py:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uskovtask.settings")

from django.core.wsgi import get_wsgi_application

_application = get_wsgi_application()

def application(environ, start_response):
    if 'USKOVTASK_PROD' in environ:
        os.environ.setdefault('USKOVTASK_PROD', environ['USKOVTASK_PROD'])
    return _application(environ, start_response)

settings.py 部分:

import os

if 'USKOVTASK_PROD' in os.environ:
    from settings_prod import *
else:
    from settings_dev import *

但它总是导入 settings_dev 的设置。为什么?

【问题讨论】:

  • 能否调试并验证 USKOVTASK_PROD 是否真的设置在 os.environ 中?您可以为此放置一个简单的打印件。
  • @iamkhush USKOVTASK_PROD 如果我在 wsgi.py 中打印它,它在 os.enivron 中,但不在 settings.py
  • 您能否通过在其后放置 print 来验证语句“if 'USKOVTASK_PROD' in environ”是否为真。
  • @iamkhush 是假的
  • 好的,那么很明显问题在于 apache conf 文件没有正确设置变量。

标签: python django apache mod-wsgi


【解决方案1】:

这与问题Access Apache SetEnv variable from Django wsgi.py file有关

如答案所说,您需要继承 WSGIHandler。

正如格雷厄姆·邓普顿在第二个答案中解释的那样,

话虽如此,您提到的博客文章通常不会有帮助。这 是因为它使用了设置过程的讨厌技巧 基于每个请求 WSGI 的每个请求的环境变量 在 Apache 中使用 SetEnv 设置环境设置。这会导致各种 多线程配置中的问题,如果 环境变量可能因 URL 上下文而异。对于的情况 Django,它没有帮助,因为 Django 设置模块会 通常在处理任何请求之前导入,这意味着 环境变量当时不可用 必填。

我认为这就是你的情况。

【讨论】:

    【解决方案2】:

    我通过将 wsgi.py 改成这样解决了这个问题:

    from django.core.handlers.wsgi import WSGIHandler
    import django
    import os
    
    class WSGIEnvironment(WSGIHandler):
    
        def __call__(self, environ, start_response):
    
            os.environ['USKOVTASK_PROD'] = environ['USKOVTASK_PROD']
            os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uskovtask.settings")
            django.setup()
            return super(WSGIEnvironment, self).__call__(environ, start_response)
    
    application = WSGIEnvironment()
    

    【讨论】:

    • 可以确认这对我来说适用于 Apache/2.2.22 (Debian)、mod_wsgi/4.4.8、Python/3.4.2、Django/1.7.3(当然,在更改 'USKOVTASK_PROD ' 和 'uskovtask.settings' 以匹配我的 ENV 变量和应用程序名称。)
    • 我使用的是 Django 1.6 并且环境变量工作正常,然后我更新到 Django 1.8 并且环境变量根本没有加载,我到处都被赋予了默认值......然后我找到了你的答案!我想这是 Django > 1.6 的路径,谢谢!
    猜你喜欢
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 2021-08-07
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多