使用 WSGI gunicorn 在 Django 中导入 Python 应用程序时出错

标签 python django import wsgi gunicorn

我正在尝试在 Heroku 上使用 gunicorn 部署 Django 应用程序,但遇到了一些问题。

当我开始我的项目时,我的 Django 版本是 1.3 并且不包含标准 wsgi.py 模块,所以我将标准 wsgi 模块添加为 top/wsgi.py(top 是我的项目名称,turk 是我的应用程序名称, topturk 是包含目录 - 保留以便错误日志在下面有意义)。

现在当我运行的时候

gunicorn top.wsgi:application -b 0.0.0.0:$PORT

服务器成功启动,

19:00:42 web.1     | started with pid 7869
19:00:42 web.1     | 2012-07-25 19:00:42 [7869] [INFO] Starting gunicorn 0.14.5
19:00:42 web.1     | 2012-07-25 19:00:42 [7869] [INFO] Listening at: http://0.0.0.0:5000 (7869)
19:00:42 web.1     | 2012-07-25 19:00:42 [7869] [INFO] Using worker: sync
19:00:42 web.1     | 2012-07-25 19:00:42 [7870] [INFO] Booting worker with pid: 7870

但是当我导航到 0.0.0.0:5000 时,我得到了一个内部服务器错误:

19:00:45 web.1     | 2012-07-25 17:00:45 [7870] [ERROR] Error handling request
19:00:45 web.1     | Traceback (most recent call last):
19:00:45 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 102, in handle_request
19:00:45 web.1     |     respiter = self.wsgi(environ, resp.start_response)
19:00:45 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 219, in __call__
19:00:45 web.1     |     self.load_middleware()
19:00:45 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 47, in load_middleware
19:00:45 web.1     |     raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
19:00:45 web.1     | ImproperlyConfigured: Error importing middleware turk.middleware.subdomain: "No module named turk.middleware.subdomain"
19:00:47 web.1     | 2012-07-25 17:00:47 [7870] [ERROR] Error handling request
19:00:47 web.1     | Traceback (most recent call last):
19:00:47 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 102, in handle_request
19:00:47 web.1     |     respiter = self.wsgi(environ, resp.start_response)
19:00:47 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 219, in __call__
19:00:47 web.1     |     self.load_middleware()
19:00:47 web.1     |   File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 47, in load_middleware
19:00:47 web.1     |     raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
19:00:47 web.1     | ImproperlyConfigured: Error importing middleware turk.middleware.subdomain: "No module named turk.middleware.subdomain"

我假设这是一个 python 路径错误,服务器不知道如何从我的应用程序目录导入

相关导入代码在设置中:

MIDDLEWARE_CLASSES = (
    'turk.middleware.subdomain.SubdomainMiddleware',
    'turk.middleware.removewww.RemoveWWWMiddleware',
)

我试图通过将我的应用程序目录插入 sys.path 来解决这个问题,就像在我的 settings.py 文件的顶部一样:

PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(1, PROJECT_ROOT+'/turk/')

我已经验证将应用程序目录添加到路径中,但仍然没有骰子。有任何想法吗?还有

sys.path.insert(1, PROJECT_ROOT+'/turk/')

似乎很老套,并且至少将目录的两个副本添加到路径中,在 Django 中附加到 PYTHON_PATH 的正确方法是什么?谢谢!

最佳答案

解决了我的问题。需要将项目目录添加到 Python 路径,而不是应用程序目录 - 即,topturk/top 而不是 topturk/top/turk 以导入 turk 目录模块。

python top/manage.py run_gunicorn

python top/manage.py runserver

工作得很好,因为根据 Python 路径文档,调用模块的目录总是作为元素 0 添加到 Python 路径元组中——因此当使用 top/manage.py 时,topturk/top 总是在Python 路径。

然而,对于 heroku,Procfile 位于项目的父目录 topturk 而不是 topturk/top,因此当运行 Procfile 命令时,topturk 被添加到 Python 路径而不是 topturk/top,因此会出现错误。

事后看来,这就是 Django 文档在本节最后一句话中所指的内容:https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/#running-django-in-gunicorn-as-a-generic-wsgi-application ,他们说为了运行这个命令,项目必须在 Python 路径上。

添加问题解决

sys.path.insert(1, os.path.dirname(os.path.realpath(__file__)))

到 settings.py 或 wsgi.py - 添加到 settings.py 就像其他人推荐的那样(http://codespatter.com/2009/04/10/how-to-add-locations -to-python-path-for-reusable-django-apps/),但不确定放置插入的最佳位置是什么。有人知道吗?

关于使用 WSGI gunicorn 在 Django 中导入 Python 应用程序时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11660627/

相关文章:

python - mitmproxy 反向代理 - 仅在非标准端口上需要 SSL

Python递归挑战

python - 如何在 Django 中为具有多个值的多对多属性的模型创建过滤器查询集

xcode - Swift:将 .csv 导入为字符串

import - 在 webpack.config 中使用 ES6 import 和 export default

python - 可以在循环内多次使用 getline() 吗? - Cython,文件读取

python - Google API Python 客户端 - AccessTokenRefreshError

Django session 数据和 Redis 作为后端

python - django:如何从数据库对象的主键中散列 URL?

Python - 导入模块的文件名不同?