【问题标题】:Django can't find locally-installed Python modulesDjango 找不到本地安装的 Python 模块
【发布时间】:2014-12-05 00:54:35
【问题描述】:

我正在运行一个基于 Django 的网站,该网站托管在共享服务器上(即我只有一个有限的帐户,没有管理员权限)。服务器的管理员安装了 Python 2.7 的 Django 模块,但现在我想添加一个名为 django-bleach 的第 3 方 Django 库。所以我在本地安装它,使用

pip install --user django-bleach

然后,按照in the django-bleach documentation 的说明,我在settings.py 的INSTALLED_APPS 列表中添加了“django-bleach”。然而,当我触摸wsgi.py 让 Apache 重新加载我的代码时,我的 Apache 日志中出现 ImportError。通常这意味着我尝试导入的模块不在 PYTHONPATH 中,所以我在 wsgi.py 中添加了 print sys.path 语句。这就是发生的事情:

[Mon Nov 24 13:44:58 2014] [error] sys.path is: ['/extra/www/html/quotes/quotes_django', '/opt/rh/python27/root/usr/lib64/python2.7/site-packages', 
'/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', 
'/usr/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib/python2.7/site-packages', '/users/ejt64/.local/lib/python2.7/site-packages',
'/users/ejt64/.local/lib/python2.7/site-packages', '/users/ejt64/.local/lib/python2.7/site-packages']
[Mon Nov 24 13:44:58 2014] [error] mod_wsgi (pid=29372): Target WSGI script '/extra/www/html/quotes/quotes_django/quotes_django/wsgi.py' cannot be loaded as Python module.
[Mon Nov 24 13:44:58 2014] [error] mod_wsgi (pid=29372): Exception occurred processing WSGI script '/extra/www/html/quotes/quotes_django/quotes_django/wsgi.py'.
[Mon Nov 24 13:44:58 2014] [error] Traceback (most recent call last):
[Mon Nov 24 13:44:58 2014] [error]   File "/extra/www/html/quotes/quotes_django/quotes_django/wsgi.py", line 17, in <module>
[Mon Nov 24 13:44:58 2014] [error]     application = get_wsgi_application()
[Mon Nov 24 13:44:58 2014] [error]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/django/core/wsgi.py", line 14, in get_wsgi_application
[Mon Nov 24 13:44:58 2014] [error]     django.setup()
[Mon Nov 24 13:44:58 2014] [error]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/django/__init__.py", line 21, in setup
[Mon Nov 24 13:44:58 2014] [error]     apps.populate(settings.INSTALLED_APPS)
[Mon Nov 24 13:44:58 2014] [error]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/django/apps/registry.py", line 85, in populate
[Mon Nov 24 13:44:58 2014] [error]     app_config = AppConfig.create(entry)
[Mon Nov 24 13:44:58 2014] [error]   File "/opt/rh/python27/root/usr/lib64/python2.7/site-packages/django/apps/config.py", line 87, in create
[Mon Nov 24 13:44:58 2014] [error]     module = import_module(entry)
[Mon Nov 24 13:44:58 2014] [error]   File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
[Mon Nov 24 13:44:58 2014] [error]     __import__(name)
[Mon Nov 24 13:44:58 2014] [error] ImportError: No module named django_bleach

请注意,/users/ejt64/.local/lib/python2.7/site-packages/ 目录在 sys.path 中出现了 3 次,是我安装 django-bleach 的用户本地 Python 位置。我使这个目录对全世界都可读,以防 Apache 进程在访问我的目录时遇到权限问题。那么我怎样才能得到 ImportError 呢?

这一定与 WSGI/Django 有关,因为如果我只是在我的 Django 应用程序目录中运行 Python,我可以这样做:

Python 2.7.5 (default, Dec  3 2013, 08:35:16) 
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django_bleach
>>> 

但我的 Django 应用程序不知何故找不到 django_bleach 模块,即使它正在寻找正确的位置。

附加信息:我的wsgi.py只是django-admin startproject生成的标准,加上打印声明:

import os 
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "quotes_django.settings")

import sys
print >>sys.stderr, "sys.path is: " + str(sys.path)

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

【问题讨论】:

  • 什么是你不用--user安装它?
  • 我不确定您的评论是什么意思。我必须使用--user 安装 django-bleach,因为我在此服务器上没有 root/sudo 权限。
  • 您的wsgi 文件是什么样的?你可以在那里映射 Python 版本。
  • 我的wsgi.py 是由Django 的startproject 命令生成的。为了以防万一,我会将其包含在我的问题中,但我不知道您所说的“映射 python 版本”是什么意思。

标签: python django apache


【解决方案1】:

好吧,我终于解决了我的问题。事实证明,尽管/users/ejt64/.local/lib/python2.7/site-packages/ 位于 WSGI 正在搜索的 PYTHONPATH 上,但我忘记将路径中的一个目录设为 world-executable,因此 Apache 用户无法访问它。

尽管所有的目录和文件都是世界可读的,但用户无法读取世界可读的文件,除非它对包含它的所有目录都具有执行权限,结果证明我的主目录 (/users/ejt64) 是世界可读但不是世界可执行的。一旦我使这个目录成为全球可执行的,ImportError 就消失了。

如果我能让 Apache/WSGI/Python 在尝试读取 PYTHONPATH 上的目录但由于权限而无法访问它时打印一条错误消息,那肯定会很好。

【讨论】:

    【解决方案2】:
    ~/.local/lib/python2.7/site-packages/
    

    相对于运行 apache 的用户。什么用户正在运行 apache?通常 apache 作为默认用户“nobody”或“apache”运行。 '~' 的相对路径将指向运行 apache 的用户的主目录。

    我建议使用 virtualenv 或指定本地 pip 包的绝对路径。进入你的站点包目录并运行pwd 会让你知道绝对路径。如果运行 apache 的用户无法读取/写入/执行它们,您可能还需要更改 pip 包和目录的权限。

    当您进入 Python REPL 时它工作正常,因为您正在以您的用户身份执行所有内容并且 '~' 指向您的主目录。

    如果您有权编辑服务器上的 apache 配置文件,我建议您查看此 Django 文档, https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/#using-a-virtualenv 如果您不使用 virtualenv 事件,您仍然需要根据本地站点包目录的绝对路径进行设置。

    WSGIPythonPath /path/to/mysite.com:/path/to/your/venv/lib/python3.X/site-packages
    

    【讨论】:

    • 您说的完全正确,但我的问题具有误导性。 Apache 打印出来的 PYTHONPATH 实际上包含了我的用户主目录的绝对路径,而不是~ 路径。我认为在示例中包含我的用户名只会使事情变得混乱。
    猜你喜欢
    • 2019-12-12
    • 1970-01-01
    • 2018-05-11
    • 2020-06-26
    • 2013-07-10
    • 2021-11-23
    • 2019-11-14
    • 2021-03-22
    相关资源
    最近更新 更多