Python Django+;mod_wsgi。从Apache设置OS环境变量';s SetEnv

Python Django+;mod_wsgi。从Apache设置OS环境变量';s SetEnv,python,django,apache,mod-wsgi,Python,Django,Apache,Mod Wsgi,我需要拆分Django的开发和生产设置。我决定,若设置了USKOVTASK\u PROD变量,那个么应用程序应该使用生产设置。我读了这篇文章并试着去做 我的片段: /etc/apache2/sites enabled/uskovstask.conf: <VirtualHost *:80> ServerName uskovtask.*.com ServerAlias uskovtask.*.com DocumentRoot /mnt/ebs/uskovtask Alias /st

我需要拆分Django的开发和生产设置。我决定,若设置了
USKOVTASK\u PROD
变量,那个么应用程序应该使用生产设置。我读了这篇文章并试着去做

我的片段:

/etc/apache2/sites enabled/uskovstask.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>
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)
import os

if 'USKOVTASK_PROD' in os.environ:
    from settings_prod import *
else:
    from settings_dev import *
settings.py的部分:

<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>
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)
import os

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

但它总是导入设置\u dev的设置。为什么?

这与问题有关

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

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

总而言之,你提到的博客帖子通常不会有帮助。这 这是因为它使用了设置流程的卑鄙伎俩 基于每个请求WSGI的每个请求上的环境变量 在Apache中使用SetEnv设置环境设置。这会导致各种各样的问题 如果 环境变量可能因URL上下文而异。就 Django,它没有帮助,因为Django设置模块 通常在处理任何请求之前导入,这意味着 环境变量在当时不可用 必需的


我想这就是你们的情况。

这与问题有关

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

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

总而言之,你提到的博客帖子通常不会有帮助。这 这是因为它使用了设置流程的卑鄙伎俩 基于每个请求WSGI的每个请求上的环境变量 在Apache中使用SetEnv设置环境设置。这会导致各种各样的问题 如果 环境变量可能因URL上下文而异。就 Django,它没有帮助,因为Django设置模块 通常在处理任何请求之前导入,这意味着 环境变量在当时不可用 必需的


我想这就是你的情况。

我通过将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()

我通过将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()

您能否调试和验证USKOVTASK_PROD是否真的在os.environ中设置?您可以对此进行简单打印。@iamkhush USKOVTASK_PROD在os.enivron中,如果我在
wsgi.py
中打印它,而不是在
settings.py
中打印它,您可以通过将print放在后面来验证“if'USKOVTASK_PROD'in environ”语句是否正确。@iamkhush它是false OK,很明显,问题在于apache conf文件没有正确设置变量。您能否调试并验证USKOVTASK_PROD是否真的在os.environ中设置?您可以对此进行简单打印。@iamkhush USKOVTASK_PROD在os.enivron中,如果我在
wsgi.py
中打印它,而不是在
settings.py
中打印它,您可以通过将print放在后面来验证“if'USKOVTASK_PROD'in environ”语句是否正确。@iamkhush它是false OK,很明显,问题出在apache conf文件没有正确设置变量上。我可以用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的路线,谢谢!我可以确认这在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.8,环境变量根本没有加载,而且到处都给了我默认值。。。然后我找到了你的答案!我想这是Django>1.6的路线,谢谢!