尝试使用mod_wsgi和virtualenv部署Django 1.4项目,我遇到了500.Apache error_log显示:
mod_wsgi (pid=30452): Exception occurred processing WSGI script '/path/to/project/site-packages/projectapp/wsgi.py'.
[...] Traceback (most recent call last):
[...] File "/path/to/project/env/myenv/lib/python2.6/site-packages/django/core/handlers/wsgi.py", line 219, in __call__
[...] self.load_middleware()
[...] File "/path/to/project/env/myenv/lib/python2.6/site-packages/django/core/handlers/base.py", line 47, in load_middleware
[...] raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
[...] ImproperlyConfigured: Error importing middleware projectapp.content.middleware: "cannot import name SomeModel"
从错误消息中我会发现这是某种路径问题。但是,当从Django设置中删除违规中间件时,网站启动很好,并且还有projectapp.content
加载的其他模块,在这种情况下也会加载SomeModel
,否则整个网站都不会“能够跑。
引发的导入错误不是直接来自中间件,因为它不会导入模型。 SomeModel
在一个speparate app中定义,该app实际上已经检入virtualenv的src目录。但是包含此应用程序的目录也在路径中。
我正在使用的wsgi.py文件:
import os
import sys
sys.stdout = sys.stderr
sys.path.insert(0, '/path/to/project/env/myenv/lib/python2.6/site-packages/')
# The module inside the following directory
# defines SomeModel from the error message
sys.path.insert(0, '/path/to/project/env/myenv/src/some-app/')
sys.path.insert(0, '/path/to/project/site-packages/')
import django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'projectapp.settings'
application = django.core.handlers.wsgi.WSGIHandler()
插入模块路径后打印sys.path
按预期顺序显示所有内容,首先列出/path/to/project/site-packages/
,然后列出/path/to/project/env/myenv/src/some-app/
(定义{{1}})秒。
我还尝试了另一种变体,基于mod_wsgi docs的例子:
SomeModel
Apache记录的错误完全相同。
我必须补充一点,当我在同一台机器上运行开发服务器时,中间件加载得很好,所以我不知道出了什么问题。有没有办法从mod_wsgi获得更好的追溯?
修改
Fogot提到我在守护进程模式下使用mod_wsgi。以下是我的vhost配置中的相关部分:
import os
import sys
import site
ALLDIRS = [
'/path/to/project/site-packages/',
'/path/to/project/env/myenv/lib/python2.6/site-packages/',
'/path/to/project/env/myenv/src/some-app/',
]
# Remember original sys.path
prev_sys_path = list(sys.path)
sys.stdout = sys.stderr
# Add each new site-packages directory
for directory in ALLDIRS:
site.addsitedir(directory)
# Reorder sys.path so new directories are 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
#activate_this = '/path/to/project/env/myenv/bin/activate_this.py'
#execfile(activate_this, dict(__file__=activate_this))
import django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'projectapp.settings'
application = django.core.handlers.wsgi.WSGIHandler()
答案 0 :(得分:0)
好的经过几个小时的调试后,结果证明这是由中间件引起的竞争条件。我正在使用的中间件与Django contrib的FlatpageFallbackMiddleware
类似,实际上视图的导入导致了问题。
from projectapp.content.views import generic_content_detail
class ContentFallbackMiddleware(object):
def process_response(self, request, response):
[...]
在process_response
方法中移动import语句解决了我的问题:
class ContentFallbackMiddleware(object):
def process_response(self, request, response):
from projectapp.content.views import generic_content_detail
[...]