如何在使用Django和WSGI时停止收到'ImportError: Could not import settings 'mofin.settings''错误?

66

我无法让wsgi导入我的名为'mofin'的项目的设置文件。

来自apache错误日志的错误列表如下

mod_wsgi (pid=4001): Exception occurred within WSGI script '/var/www/wsgi-scripts/django.wsgi'.
Traceback (most recent call last):
  File "/usr/lib/python2.5/site-packages/django/core/handlers/wsgi.py", line 228, in __call__
    self.load_middleware()
  File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py", line 31, in load_middleware
    for middleware_path in settings.MIDDLEWARE_CLASSES:
  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 28, in __getattr__
    self._import_settings()
  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 59, in _import_settings
    self._target = Settings(settings_module)
  File "/usr/lib/python2.5/site-packages/django/conf/__init__.py", line 94, in __init__
    raise ImportError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e)
ImportError: Could not import settings 'mofin.settings' (Is it on sys.path? Does it have syntax errors?): No module named mofin.settings

我成功使用此处列出的"wsgi"应用程序(http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide)。

设置文件settings.py可以通过python manage.py(runserver|shell|syncdb|test store)正常加载,应用程序也是如此。

这是我的wsgi文件:

import os
import sys
sys.path.append('/home/django/mofin/trunk')
sys.path.append('/home/django/mofin/trunk/mofin')
print >> sys.stderr, sys.path
os.environ['DJANGO_SETTINGS_MODULE'] = 'mofin.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

在错误日志中打印的sys.path如下:
['/usr/lib/python25.zip', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages/gtk-2.0', '/home/django/mofin/trunk', '/home/django/mofin/trunk/mofin']
如果我使用manage.py打开交互式shell,sys.path如下:
['/home/django/mofin/trunk/mofin', '/usr/lib/python25.zip', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages/gtk-2.0']
我的Django设置文件如下:# Django settings for mofin project.
DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    # ('Dan xxxx', 'xxxx@yyyyyyyyyy.com'),
)

MANAGERS = ADMINS

DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'mofin'             # Or path to database file if using sqlite3.
DATABASE_USER = 'aaaaaa'             # Not used with sqlite3.
DATABASE_PASSWORD = 'bbbbbb'         # Not used with sqlite3.
DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'Europe/London'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-GB'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = '/home/django/media/'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = 'http://mofin.mywebsite.co.uk/media/'

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/admin_media/'

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
#     'django.template.loaders.eggs.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

ROOT_URLCONF = 'mofin.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'mofin.store'
)

2
请查看此问题的答案:https://dev59.com/MlHTa4cB1Zd3GeqPV-0V - radztech
15个回答

48

如果您有一个与项目同名的应用程序(子目录带有init文件),则也可能会出现这种情况。您的settings.py文件可能在项目文件夹中,但是似乎django系统的一部分首先查找与项目同名的模块,当它在其中找不到settings.py时,就会失败并显示具有误导性的消息。

-uniquename1

---settings.py

---manage.py

---application1

-----file.py

-----file2.py

---uniquename1  (problem, rename this to some other unique name)

-----file.py

-----file2.py

对于其他遇到这个问题的人,还有一些需要检查的东西。适用于Django 1.3和可能的其他版本。


4
除了重命名目录之外,是否还有其他的解决方案? - Dmytriy Voloshyn
我当时没有寻找解决方案,但如果这个问题仍然存在,我猜想开发人员还没有将其作为优先事项。深入探究其原因已经超出了我的能力范围。我相信这是在核心系统中需要进行更改的问题。 - shanemgrey
我不认为你是对的,Shaneveeg。在我的情况下,“settings.py”位于项目文件夹的“第二层”,如在执行“django-admin.py startproject mysite”时所见:https://docs.djangoproject.com/en/1.6/intro/tutorial01/ - Timo

22

我遇到了类似的权限问题,虽然我的settings.py有正确的权限,但是.pyc文件却没有!!!所以要注意一下这个问题。


6
+1 刚遇到和 OP 相似的问题,移除 *.pyc 文件后问题得以解决,所以感谢。这个看起来很好用 alias rmpyc="find . -name "*.pyc" -exec rm -rf {} \;" 用于“清理”一个项目。 - T I

18

嘿,我来给这个问题添加一个额外的答案。我曾经碰到过完全相同的问题,但问题不在于文件权限。我附加了“path/to/project”,但没有附加“path/to”。这里有mod_wsgi关于Django集成解释,它向我展示了正确的答案。


4
在其他Python语句之前加入以下内容即可解决问题。感谢提示 :-)import os, sys base = os.path.dirname(os.path.dirname(__file__)) base_parent = os.path.dirname(base) sys.path.append(base) sys.path.append(base_parent) - JWL

8
我找到了答案...是文件权限的问题。/home/django的权限被设置为700,即只有django可以查看其中的内容。而Apache运行时以Apache身份运行,因此无法越过/home/django这个目录。

8
给定一个目录,让Apache读取它,最安全的权限是什么? - Tony Adams

7

我认为你需要在结尾添加斜杠,这是我在加载Django之前在Apache的WSGI脚本中必须做的。

import os
import sys
sys.path.append('/home/django/mofin/trunk/')
sys.path.append('/home/django/mofin/trunk/mofin/')
print >> sys.stderr, sys.path
os.environ['DJANGO_SETTINGS_MODULE'] = 'mofin.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

在我的情况下
import os
import sys
if os.uname()[1] == 'vivien':
    sys.path.append('/home/www/sitebuilder.blacknight.ie/web/')
    os.environ['DJANGO_SETTINGS_MODULE'] = 'gibo.dev_settings'
elif os.uname()[1] == 'thingy':
    sys.path.append('/home/www/sitebuilder.blacknight.ie/web/')
    os.environ['DJANGO_SETTINGS_MODULE'] = 'gibo.dev_settings'
else:
    sys.path.append('/home/www/sitebuilder.blacknight.ie/web/')
    os.environ['DJANGO_SETTINGS_MODULE'] = 'gibo.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

这是我的问题。加入第二个追加语句解决了它!感谢您的帮助! - Nathan Jones
有人应该给这个答案点赞!当你添加到PYTHONPATH时,需要加上尾部斜杠。太荒谬了!它浪费了我一个小时的时间。 - Dexter Legaspi

6
这个问题的另一个原因是你不能将应用程序命名为与另一个Python模块相同的名称。例如,我把我的称为site,并没有意识到site已经是一个Python模块。
你可以通过启动Python并运行import sitehelp(site)来检查它是否正在使用你的模块。当Django尝试导入不存在的site.settings时,这显然会给你带来错误。

4
可能的问题:
您可能忘记了 __init__.py 文件,该文件必须在您的项目中以及您认为是 Python 模块以进行导入的所有目录中。
您可以尝试的另一件事是直接在 manage.py 文件中添加路径,例如:
import sys

...
...

sys.path.insert(0, '/home/django/mofin/trunk')

我希望这能对你有所帮助。


谢谢Xidobix,我找到了另一个没有__init__.py文件的模块,修复了runserver上的管理站点,但这仍然无法正常工作。直接添加路径也没有解决问题。我想我会创建一个非常简单的项目并尝试让它正常工作,然后再从那里继续。 - Dan
我已将它简化得更多,并创建了一个名为"peanut"的新项目,使用命令"django-admin.py startproject peanut"。 修改了wsgi文件指向"peanut.settings"。 在使用runserver时,peanut可以正常工作,但在使用wsgi时出现相同的错误。这可能与文件权限、文件所有权或其他环境变量有关。这些变量在runserver和wsgi之间是不同的。 - Dan
Dan,我真的从来没有使用过WSGI,我使用mod_python。但是在你正在阅读的指南的结尾,有一个链接指向http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango。那里一定有你要找的答案。祝你好运! - Xidobix

3
我遇到了同样的问题,但是另一种解决方法如下:
我的项目文件夹与我其中一个应用程序的名称完全相同。
我有:
/home/myApp /home/myApp/settings.py /home/myApp/manage.py /home/myApp/rights.py /home/myApp/static/ /home/myApp/static/ /home/myApp/myApp/model.py /home/myApp/myApp/admin.py /home/myApp/myApp/views.py
这种树形结构似乎不容易实现。我改变了项目根目录文件夹的名称,问题得到了解决!

1
我相信现在已经可以实现(1.4),因为我没有看到这个问题。https://code.djangoproject.com/ticket/1908 - John Lehmann
1
只有在项目根文件夹中存在__init__.py文件时,才会出现此问题,因为它会误导导入程序认为这是一个可导入的模块(而不是查看其中同名模块)。 - tato

1
在我的情况下,我有一个导致此错误的循环导入。从settings.py中,我在另一个模块中导入了一个函数,并从该模块中导入了一个设置变量。为了修复它,我没有直接从设置中导入,而是这样做:
from django.conf import settings

1

在使用守护程序模式时,即使我与错误日志中显示的Python主目录一起设置了PYTHONPATH,它仍然会在错误日志中不断显示“PYTHONPATH =(未设置)”。你知道为什么会发生这种情况吗? - imran.ke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接