通过mod_wsgi从apache传递环境变量以在django 1.11设置中使用

时间:2018-01-19 12:04:54

标签: django apache mod-wsgi

找到了这个问题的几个版本,例如Django get environment variables from apache,但是到目前为止我找到的建议似乎与最新的LTS django(1.11)无关。

我有一个apache配置,它包含许多环境变量,不仅限于DB的连接凭据。我使用它来使我的代码可以在dev / prod等之间移植。

我的apache conf只使用SetEnv传递一些变量。

我尝试了两种不同风格的方法来使用这些变量,两者似乎都遇到了同样的问题;它需要在我们写入环境之前读取设置文件,并且设置文件需要来自环境的值。

我的两个变种是;

import os
import django
from django.core.handlers.wsgi import WSGIHandler

from django.core.wsgi import get_wsgi_application

_application = get_wsgi_application()

def application(environ, start_response):
  for key in [keys...]:
    if environ.get(key):
        os.environ[key] = environ.get(key)
  return _application(environ, start_response)

import os
import django
from django.core.handlers.wsgi import WSGIHandler

class WSGIEnvironment(WSGIHandler):
    def __call__(self, environ, start_response):
        for key in [keys...]:
            if environ.has_key(key):
                print "Key: %s = %s" % (key,environ[key])
                os.environ[key] = environ[key]
        return super(WSGIEnvironment, self).__call__(environ, start_response)

os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'apiClient.settings')
django.setup(set_prefix=False)
application = WSGIEnvironment()

我试图将设置中的值用作;

KEY = "thing"

if os.environ.has_key("KEY"):
    KEY = os.environ["KEY"]

3 个答案:

答案 0 :(得分:1)

您无法使用SetEnv,因为在处理第一个请求之前会评估设置文件。根据每个请求设置环境变量WSGI环境值总是一个坏主意,可能会导致问题,所以你不应该这样做。

结果是您无法从Apache配置文件中设置环境变量。从WSGI脚本文件中设置它们。如果它们是不应该添加到Git存储库的东西,则使用某种格式的值在特定主机上创建文件,并让WSGI脚本文件从本地主机读取该文件,以便在首次加载时和之前设置它们。执行Django代码。

答案 1 :(得分:1)

对于Django> 1.7,get_wsgi_application调用django.setup()来初始化设置。因此,如果此时未设置环境变量,则不会在设置中看到它们。

要解决此问题,请在准备好之前不要真正调用get_wsgi_application。在wsgi.py中对我有用:

def application(environ, start_response):
    os.environ['APPLICATION_ENV'] = environ.get('APPLICATION_ENV', None)
    return get_wsgi_application()(environ, start_response)

答案 2 :(得分:0)

你必须推迟初始化Django应用程序直到第一个请求。你的wsgi.py中有这样的东西:

from django.core.wsgi import get_wsgi_application
_application = None
def application(environ, start_response):
    global _application
    if _application == None:
        for key in environ:
            if key.startswith('ENV_'):
                os.environ[key[4:]] = environ[key]
        _application = get_wsgi_application()
    return _application(environ, start_response)

遗憾的是,mod_wsgi中似乎没有选项可以在启动守护进程时设置初始环境,就像使用mod_fastcgi一样。