获取 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 顺便说一句,你放错了abspathdirname。应该是相反的。 @ahmoo 也可以通过import appname; os.path.abspath(appname.__path__)获取应用路径。 @Dougal - 谢谢。 appname.__path__ 正是我要找的。添加您的评论作为解决方案,我会接受。

以上是关于获取 django 应用的绝对路径的主要内容,如果未能解决你的问题,请参考以下文章

web应用路径问题(相对路径,绝对路径,动态获取路径)

C#获取文件物理路径(绝对路径)

C#获取文件物理路径(绝对路径)

在web应用中获取相对路径和绝对路径

Django:配置设置.py依赖相对路径而不是绝对路径

获取资源绝对路径的方法