settings.py无法导入:Django之谜
不要尝试在Django项目文件夹里创建与项目同名的.py模块。
不然……就会像尼克同学一样遇到大麻烦。。
一、settings.py导入失败
之前尼克同学在玩Django的时候遇到了一点小麻烦。他用Eclipse创建了一个项目,结果怎么也跑不起来。于是我让他用manage.py shell启动交互控制台试试,结果报的是一样的错误:
...>manage.py shell Error: Could not import settings 'helloworld.settings' (Is it on sys.path? Does it have syntax errors?): No module named settings
错误的意思是,该项目的settings.py文件没有导入成功。
二、初步排查
于是我开始了一系列的排错过程。
我主要是用到了对照的办法,在自己机器上创建了一个空项目,与尼克的项目进行比较。
1、是否和Python版本或Django版本有关?
尼克用的是PY27和Django 1.2。于是我让他把代码打包传给我运行。错误依旧。
打包给尼克运行,可以使用。
2、是否Eclipse创建的项目有特殊性?
我跟尼克的两个manage.py一模一样。
settings.py略有不同,但我猜应该不是决定性因素。
3、我们的项目还有什么不同?
尼克的项目比我多一个helloworld.py文件;尼克在urls.py中对“/”(主页)进行了匹配:
urlpatterns = patterns('',
(r'^$', 'helloworld.helloworld.index')
)
4、猜测:urls.py有语法错误?
会不会是settings.py中可能引用了urls.py,而urls.py中有语法错误,从而导致settings.py抛出异常,造成导入settings.py失败?
不是的,单独执行urls.py,没有任何提示,说明没有语法错误。
到这里我已经没有思路了,既然我传给尼克的项目没有问题,尼克可以在那个项目里继续写代码。
我也告诉尼克可以用django-admin.py创建项目:
E:\Pub\dj11>django-admin.py startproject another_helloworld
这样建出来的空项目似乎都可以工作。那么也许毛病出走Eclipse上?不好说,但是考虑到还有别的难题等着我,这个谜一般的行为我也只好暂时搁置了。
三、这都是有原因的
大家可能有过这样的体会,有的时候电脑启动不了,发出嘟嘟的响声,对着机箱砸几拳就好了。
久而久之有种印象,计算机相关的各种问题,都是稀里糊涂地不明就里地解决的。
死Coder们的程序出了BUG,这里瞎改改,那里瞎改改,OK了,就再不追究一个为什么。
但叫兽说过,这都是有原因的,有原因的。对着机箱砸几拳,原来接触不良的地方可能就接上了,这不是超自然现象,这是科学。
连CCAV都敢走近科学,我觉得我也是时候揭开其中的玄机了。
四、罪魁祸首
重新检查我跟尼克项目的不同:
1、manage.py、__init__.py
前面提到过,manage.py是一样的。
__init__.py都是空文件,这也很正常。(Python里面,有这个文件,就表示这个文件夹里的模块们构成一个package)
2、settings.py
把尼克settings.py里不同的地方一一替换成我的版本,仍未发现问题。
我干脆拿我的settings.py替换尼克的,错误依旧。
3、urls.py
我拿我的urls.py替换了尼克的,错误依旧。
至此,我跟尼克项目里的同名文件已经对比排查完毕。
4、helloworld.py
尼克的项目里多了这个文件,是自己编写用来响应“/”这个URL的。
我将它移出项目,奇迹发生了……错误消失了!
终于锁定了犯罪嫌疑人——就是那个多出的helloworld.py。
五、刨根问底
按照有关部门的作风,我已经可以对helloworld.py进行公捕公判,游街示众了。
但是,我是一个讲法治的人,我是以事实为依据,以法律为准绳的。不能放过一个坏人,更不能冤枉一个好人。
关键的问题在于,它到底犯了什么罪?
猜想:helloworld.py恰好与项目helloworld同名,难道这个就是问题所在?

10. August 2010 at 14:29
[...] 前文提到,似乎在Django项目中创建与项目名同名的文件,就会引起settings.py导入错误。 [...]