【发布时间】:2012-04-08 12:39:14
【问题描述】:
我正在编写一个单元测试,它需要访问我放在 django 应用程序目录下的“fixtures”目录中的图像文件。我想在我的测试中使用相对路径打开这个图像文件,这需要我获取 django 应用程序的绝对路径。有没有办法获取 django 应用的绝对路径?
【问题讨论】:
我正在编写一个单元测试,它需要访问我放在 django 应用程序目录下的“fixtures”目录中的图像文件。我想在我的测试中使用相对路径打开这个图像文件,这需要我获取 django 应用程序的绝对路径。有没有办法获取 django 应用的绝对路径?
【问题讨论】:
Python3.4及以上版本自带标准库pathlib。
from pathlib import Path
import appmodule
pth = Path(appmodule.__file__).parent / 'fixtures'
if pth.exists():
"Your code here"
parent 将为您提供应用目录的路径,/ 将附加固定装置作为路径。
【讨论】:
较新版本的 Django(我不知道它是什么时候开始的,我想它已经存在很多年了),默认的 settingy.py 包含一个条目
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
您可以通过像这样导入设置文件来使用它
import os
from my_project_name.settings import BASE_DIR
os.path.join(BASE_DIR, ...)
【讨论】:
因此,接受的答案通常可以正常工作。但是,对于
他们的预期路径可能与模块的__file__ 属性不一致。
Django (1.7+) 提供了AppConfig.path 属性——我认为即使在简单的情况下也更清楚,并且也涵盖了这些边缘情况。
The application docs 告诉你如何获取 AppConfig 对象。所以要获取 AppConfig 并从中打印路径:
from django.apps import apps
print(apps.get_app_config('app_label').path)
编辑:
更改了如何使用get_app_config 删除点的示例,这似乎令人困惑。 Here are the docs for reference.
【讨论】:
name(例如 namespace.baz.foo)。如果在不同的命名空间中有 2 个名为“foo”的标签,这会使事情变得更加复杂......
get_app_config() 会引发 LookupError,所以这个答案并不是一个很好的答案。
请记住,appname.__path__ 是一个列表:
import appname
APP_ROOT = os.path.abspath(appname.__path__[0])
file_path = os.path.join(APP_ROOT, "some_file.txt")
【讨论】:
Python 模块(包括 Django 应用程序)有一个 __file__ 属性,它告诉您它们的 __init__.py 文件在文件系统上的位置,所以
import appname
pth = os.path.dirname(appname.__file__)
应该做你想做的。
在通常情况下,os.path.absname(appname.__path__[0]),但如果应用想要以奇怪的方式导入文件,则可以更改它。
(不过,我总是在 settings.py 中使用 PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) ——这使得需要绝对路径的各种设置变得容易。)
【讨论】:
appname.__path__[0],虽然看起来有可能改变它;你也可以使用os.path.dirname(appname.__file__),因为__file__指向__init__.py文件。
通常,这是我在 settings.py 文件中添加的内容,因此我可以引用项目根目录。
import os.path
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
此方法将获取任何python文件的目录。
【讨论】:
abspath和dirname。应该是相反的。
import appname; os.path.abspath(appname.__path__)获取应用路径。
appname.__path__ 正是我要找的。添加您的评论作为解决方案,我会接受。