获取 django 应用的绝对路径
Posted
技术标签:
【中文标题】获取 django 应用的绝对路径【英文标题】:Get absolute path of django app 【发布时间】:2012-04-08 12:39:14 【问题描述】:我正在编写一个单元测试,它需要访问我放在 django 应用程序目录下的“fixtures”目录中的图像文件。我想在我的测试中使用相对路径打开这个图像文件,这需要我获取 django 应用程序的绝对路径。有没有办法?
【问题讨论】:
【参考方案1】:Python3.4及以上版本自带标准库pathlib
。
from pathlib import Path
import appmodule
pth = Path(appmodule.__file__).parent / 'fixtures'
if pth.exists():
"Your code here"
parent
将为您提供应用目录的路径,/
将附加固定装置作为路径。
【讨论】:
【参考方案2】:较新版本的 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, ...)
【讨论】:
【参考方案3】:因此,接受的答案通常可以正常工作。但是,对于
具有多个路径的命名空间包,或者 在配置中明确配置其路径的应用,他们的预期路径可能与模块的__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.
【讨论】:
这是 Django 1.7+ 版本的正确答案,但由于应用注册表尚未准备好,因此无法在设置中使用 谢谢。使用 Django 版本编辑答案。 另外值得注意的是,接受的答案在设置中也不起作用,因为它需要导入应用程序。如果您在设置中找到了一种优雅的方式来执行此操作,@RobM,那么值得发布! :) 另外提一下,get_app_config() 需要一个 app_label(例如“foo”),而不是应用程序的name
(例如 namespace.baz.foo)。如果在不同的命名空间中有 2 个名为“foo”的标签,这会使事情变得更加复杂......
顺便说一句:将虚线名称传递给 get_app_config()
会引发 LookupError,所以这个答案并不是一个很好的答案。【参考方案4】:
请记住,appname.__path__
是一个列表:
import appname
APP_ROOT = os.path.abspath(appname.__path__[0])
file_path = os.path.join(APP_ROOT, "some_file.txt")
【讨论】:
【参考方案5】: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__ 是列表,而不是字符串。见docs.python.org/2/tutorial/… @GeorgeLund 你是对的,当然;我真傻。你可以做appname.__path__[0]
,虽然看起来有可能改变它;你也可以使用os.path.dirname(appname.__file__)
,因为__file__
指向__init__.py
文件。
您能否更改答案以匹配您的评论,因为答案是大多数人首先看到的。
@Igor 当然,改了。
注意现在Django提供了settings.BASE_DIR,见:***.com/a/32156582/1104244【参考方案6】:
通常,这是我在 settings.py 文件中添加的内容,因此我可以引用项目根目录。
import os.path
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
此方法将获取任何python文件的目录。
【讨论】:
这很聪明,但它提供了项目的路径而不是应用程序。就我而言,它会正常工作,因为在文件系统中,我的应用程序位于项目下,否则它不会成功。有什么方法可以让我真正获得应用程序的路径吗?或者这是我能得到的最接近的? 您可以在恰好位于应用程序中的文件中使用它,或者使用 os.path.join() 将文件夹中应用程序的路径附加到 PROJECT_ROOT 顺便说一句,你放错了abspath
和dirname
。应该是相反的。
@ahmoo 也可以通过import appname; os.path.abspath(appname.__path__)
获取应用路径。
@Dougal - 谢谢。 appname.__path__
正是我要找的。添加您的评论作为解决方案,我会接受。以上是关于获取 django 应用的绝对路径的主要内容,如果未能解决你的问题,请参考以下文章