我正在开发一个Django项目,我正在尝试为我在其中创建的应用程序设置URLConf。 (你真的不需要理解Django来理解我的问题)
以下是我项目的相关部分
/PROJECT
__init__.py
settings.py
urls.py
/home
__init__.py
views.py
/user
__init__.py
views.py
我正在尝试从home
导入PROJECT/urls.py
:
PROJECT/urls.py (relevant parts)
from django.conf.urls import url, include
from django.contrib import admin
import user
import home # <---
urlpatterns = [
url(r'^$', home.views.index, name='index'), # <---
url(r'^register/$', user.views.register, name='register'),
url(r'^login/$', user.views.login, name='login'),
url(r'^logout/$', user.views.logout, name='logout'),
]
由于某些原因导入user
有效,导入home
(及其子模块)不。
当我运行Django内置的Web服务器时,我收到错误:
AttributeError: module 'home' has no attribute 'views'
我不导致导入user
及其子模块的错误
我应该注意到,当我在普通的python shell中运行urls.py
时,它会返回home
和user
的导入错误,但我只有home
错误运行Django的网络服务器。我的代码的user
部分从一开始就运行良好,我认为它在普通shell中是错误的,因为它本身不应该运行。
同样,由于某种原因,我无法理解,user
正确导入,而home
则没有,尽管它们之间没有明显差异。
这是在Python 3.5.1和Django 1.9
中答案 0 :(得分:0)
使用此:
import home.views
在Python中导入包时,它不会递归导入其中包含的所有子包或模块。
import user
工作的原因并不明显,但可能是因为您要在user/__init__.py
内导入视图。除此之外,在user.views
调用中访问url
之前,另一个模块也可能导入views
。这使得Python在user
包的名称空间中插入了/tmp/importtest $ mkdir mod_a mod_b
/tmp/importtest $ touch mod_{a,b}/__init__.py
/tmp/importtest $ echo 'A=1' > mod_a/a.py
/tmp/importtest $ echo 'B=2' > mod_b/b.py
/tmp/importtest $ echo 'import mod_b.b' > mod_c.py
/tmp/importtest $ python
Python 3.4.3 (default, Jan 4 2016, 22:02:53)
[GCC 4.9.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mod_a, mod_b
>>> mod_a.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'a'
>>> mod_b.b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'b'
>>> import mod_c
>>> mod_b.b
<module 'mod_b.b' from '/tmp/importtest/mod_b/b.py'>
>>> mod_a.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'a'
>>>
模块。
考虑以下示例:
mod_c
正如您所看到的,在导入mod_b
之前,mod_c
内没有任何内容,但导入b
后更改了一次,因为它有插入{{的副作用1}}对象进入mod_b
的命名空间。
这会让它更清楚吗?
总之,如果您想要访问user.views
或home.views
,请始终导入user.views
和home.views
,而不是仅导入顶级包并希望其他内容恰好有副作用。
答案 1 :(得分:0)
常见的解决方案是将home
文件夹添加到python环境中。
# in your Django settings
import os
import sys
PROJECT_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_DIR = os.path.dirname(PROJECT_DIR)
# add here
sys.path.append(os.path.join(PROJECT_DIR, "home"))
# now you can use home
from home import view
python2和python3中的相对导入也有所不同。