Python 在Django管理命令中读取文件

Python 在Django管理命令中读取文件,python,django,Python,Django,我正在尝试使用gspread读取GoogleSheetsAPI的凭据。我编写了以下代码: class Command(BaseCommand): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def handle(self, *args, **kwargs): scope = ['https://spreadsheets.google.com/feed

我正在尝试使用gspread读取GoogleSheetsAPI的凭据。我编写了以下代码:

class Command(BaseCommand):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def handle(self, *args, **kwargs):
        scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']

        credentials = ServiceAccountCredentials.from_json_keyfile_name('/static/json/spreadsheets.json', scope)

        gc = gspread.authorize(credentials)

        wks = gc.open("Where is the money Lebowski?").sheet1

        self.stdout.write(self.style.SUCCESS('Succesfully ran "sheets" command'))
读取文件会返回以下错误:

FileNotFoundError: [Errno 2] No such file or directory: 'static/json/spreadsheets.json'
我尝试了多种路径,如:

  • “~/static/json/spreadsheets.json”
  • “/json/spreadsheets.json”
  • 'spreadsheets.json'

但似乎都不管用。有人能帮我吗?

当您使用绝对路径时,它是从文件系统的根开始的,即
/

当您使用相对路径时,即在开始时不使用
/
,它是从调用脚本的目录解析的,而不是从脚本实际位于文件系统中的目录解析的

因此,当您通过例如
/manage.py
调用Django管理命令时,它会查找从当前目录
manage.py
开始的路径,即
os.path.dirname('manage.py')
。如果将路径指定为
static/json/spreadsheets.json
,则它查找的完整路径为:

os.path.join(
    os.path.abspath(os.path.dirname('manage.py')),
    '/static/json/spreadsheets.json'
)
因此,您需要确保在正确的目录中有
spreadsheets.json
文件。更好的方法是对此类场景使用绝对路径。如果您使用的是GNU/Linux,则可以使用:

readlink -f static/json/spreadsheets.json
获取绝对路径



此外,您应该将文件作为管理命令的参数,而不是硬编码文件。Django管理命令用于参数解析,因此您可以首先查看。

符号:
~
符号在本例中不起作用,因为它只是一个glob,正由*nix shell扩展到完整路径,因此在本例中无法扩展,因为这里不涉及shell。 前导的
/
符号将把您移动到根目录

我不知道所有情况(因为您没有提供有关运行此命令的目录以及与该目录相比文件所在位置的信息)

但您可以使用
os
库中的方法
getcwd
,如下所示:

import os
print(os.getcwd())
或者从调试器获取当前位置。然后,您可以将绝对路径传递到文件,或者在需要时使用“.”访问父目录,甚至使用
os.chdir()更改当前工作目录
方法,但不建议这样做,因为它可能会对Django或project中使用的其他库产生一些副作用,这些库不希望在运行时更改目录