经过很长一段时间,我在Django写的一个应用程序没有完成,我已经在一台新Mac上回来了。
我很难让代码在没有显式路径的情况下引用应用程序及其中的文件。例如:
from myproject.app.file import object
我记得每次都不必使用myproject
。
这是改变了吗?我似乎记得要添加到每次运行开发服务器时调用的manage.py
中的路径,但这次没有用。
sys.path.append /path/to/myproject
这应该解决我遇到的问题吗?
答案 0 :(得分:2)
我从一个简单的答案开始,它变得更详细地介绍了如何将项目的子目录添加到python路径。也许有点偏离主题,但它可能对你有用,所以我无论如何都要按下发布按钮。
我通常有一堆小的可重复使用的应用程序,我保留在项目树中,因为我不希望它们成长为独立的模块。我的项目树将如下所示:
manage.py
myproject/apps
myproject/libs
myproject/settings
...
但是,默认情况下,Django只将项目根添加到python路径。然而,在我看来,让应用程序加载具有完整路径的模块是没有意义的:
from myproject.apps.author.models import Author
from myproject.libs.rest_filters import filters
这两种方式都过于冗长,并且因为我只使用绝对导入而破坏了可重用性。更不用提我是否有一天会从某些lib中构建一个实际的python包,它会破坏。
所以,我采取了以下步骤。我将相关文件夹添加到路径中:
# in manage.py
root = os.path.dirname(__file__)
sys.path.append(os.path.realpath(os.path.join(root, 'myproject', 'apps')))
sys.path.append(os.path.realpath(os.path.join(root, 'myproject', 'libs')))
但是你必须确保无法从项目的根目录加载这些包,否则你会遇到奇怪的问题,因为python会加载模块的另一个副本。例如,isinstance(libs.foo.bar(), myproject.libs.foo.bar) == False
虽然不难:只需从添加到路径中的文件夹中删除__init__.py
即可。这将确保他们不能从项目中进入。
此外,除非您手动指定,否则Django的发现跑步者不会进入这些路径。这对您来说可能没问题(如果每个模块都有自己的测试套件)。或者你可以扩展跑步者,所以它知道这个:sample code。