python - Django/Apache/mod_wsgi 不使用 virtualenv 的 Python 二进制文件

标签 python django apache mod-wsgi wsgi

我在/opt/webapps/ff/有一个 virtualenv,它有自己的 Python 安装。我在我的 Apache 配置文件中将 WSGIPythonHome 设置为/opt/webapps/ff(这肯定会以某种方式使用,因为如果我将它设置为稍微不同的现有目录并重新启动 Apache,我会得到 504)。但是如果我例如assert False 在某处的 View 中调出 Django 调试页面,我看到 settings.PYTHON_BIN 是 /usr/bin 而不是 /opt/webapps/ff/bin.

如何让 Apache/mod_wsgi 使用我的虚拟环境的 Python 二进制文件?我认为设置 WSGIPythonHome 是执行此操作的方法,但它似乎只影响使用哪个站点包目录,而不影响使用哪个二进制文件。谢谢。

最佳答案

这些是我使用的说明,似乎运行良好。

http://code.google.com/p/modwsgi/wiki/VirtualEnvironments

Using 'site.addsitedir()' is a bit different to simply adding the directory to 'sys.path' as the function will open up any '.pth' files located in the directory and process them. This is necessary to ensure that any special directories related to Python eggs are automatically added to 'sys.path'.

Note that although virtualenv includes the script 'activate_this.py', which the virtualenv documentation claims should be invoked using 'execfile()' in the context of mod_wsgi, you may want to be cautious using it. This is because the script modifies 'sys.prefix' which may actually cause problems with the operation of mod_wsgi or Python modules already loaded into the Python interpreter, if the code is dependent on the value of 'sys.prefix' not changing. The WSGIPythonHome directive already described should instead be used if wanting to associate Python as a whole with the virtual environment.

Despite that, the 'activate_this.py' script is an attempt to resolve an issue with how 'site.addsitedir()' works. That is that any new directories which are added to 'sys.path' by 'site.addsitedir()' are actually appended to the end. The problem with this in the context of mod_wsgi is that if WSGIPythonHome was not used to associate mod_wsgi with a virgin baseline environment, then any packages/modules in the main Python installation will still take precedence over those in the virtual environment.

To work around this problem, what 'activate_this.py' does is invoke 'site.addsitedir()' but then also reorders 'sys.path' so any newly added directories are shifted to the front of 'sys.path'. This will then ensure that where there are different versions of packages in the virtual environment that they take precedence over those in the main Python installation.

As explained, because 'activate_this.py' is doing other things which may not be appropriate in the context of mod_wsgi, if unable to set WSGIPythonHome to point mod_wsgi at a virgin baseline environment, instead of just calling 'site.addsitedir()' you should use the code:

ALLDIRS = ['usr/local/pythonenv/PYLONS-1/lib/python2.5/site-packages']

import sys 
import site 

# Remember original sys.path.
prev_sys_path = list(sys.path) 

# Add each new site-packages directory.
for directory in ALLDIRS:
  site.addsitedir(directory)

# Reorder sys.path so new directories at the front.
new_sys_path = [] 
for item in list(sys.path): 
    if item not in prev_sys_path: 
        new_sys_path.append(item) 
        sys.path.remove(item) 
sys.path[:0] = new_sys_path 

If you still want to use the activation script from virtualenv, then use:

activate_this = '/usr/local/pythonenv/PYLONS-1/bin/activate_this.py' 
execfile(activate_this, dict(__file__=activate_this))

If the fact that 'sys.prefix' has been modified doesn't give an issue, then great. If you see subtle unexplained problems that may be linked to the change to 'sys.prefix', then use the more long handed approach above whereby 'site.addsitedir()' is used directly and 'sys.path' reorderd subsequently.

这里也有关于这个问题的讨论

http://groups.google.com/group/modwsgi/browse_thread/thread/466823f087070b5f?pli=1

关于python - Django/Apache/mod_wsgi 不使用 virtualenv 的 Python 二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5800608/

相关文章:

python - 将 2 个暗淡的 numpy 数组与向量相乘得到 3 个暗淡的数组

python - 在 pandas 中分割时间戳日期

python - Django 在给定的 url 上调用了错误的函数

java - Apache Camel 中的解码 (JSON)

ajax - 如何配置 apache 以使用 Access-Control-Allow-Origin header 处理多个域?

python - Django ManyToMany 字段为 json 格式

python - 如何去除图像中对象的边缘噪声

python - 如何为 Django 创建一个唯一的随机用户名?

python - Django 聚合过滤器

java - Android Studio java.lang.NoSuchMethodError : No static method encodeHexString