Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django storages dropbox.stone_validators.ValidationError_Python_Mysql_Json_Django_Dropbox - Fatal编程技术网

Python django storages dropbox.stone_validators.ValidationError

Python django storages dropbox.stone_validators.ValidationError,python,mysql,json,django,dropbox,Python,Mysql,Json,Django,Dropbox,我正在尝试使用dropbox作为媒体素材。我正在尝试通过django存储实现 设置.py models.py 错误 请求方式:| POST 请求URL:| Django版本:| 2.1.8 异常类型:| ValidationError 异常值:|'D:/media/10506738_10150004552801856_220367501106153455_o.jpg'与模式'/.[\r\n]| id:.|版本:[0-9a-f]{9,}ns:[0-9]+/.' 控制台 dropbox.stone_

我正在尝试使用dropbox作为媒体素材。我正在尝试通过django存储实现

设置.py

models.py

错误

请求方式:| POST

请求URL:|

Django版本:| 2.1.8

异常类型:| ValidationError

异常值:|'D:/media/10506738_10150004552801856_220367501106153455_o.jpg'与模式'/.[\r\n]| id:.|版本:[0-9a-f]{9,}ns:[0-9]+/.'

控制台

dropbox.stone_validators.ValidationError:'D:/media/10506738_10150004552801856_220367501106153455_o.jpg'与模式'/.[\r\n]| id:.| rev:[0-9a-f]{9,}ns:[0-9]+/.'


我不明白为什么会发生此错误?

此错误消息来自Dropbox API,表明为Dropbox API调用提供的路径没有预期的格式。例如,如果您正在上载一个文件,那么您提供的路径将是Dropbox帐户中您希望将上载数据放在其中的路径

您正在提供以下值:

D:/media/10506738_10150004552801856_220367501106153455_o.jpg

这似乎是一个本地Windows文件系统路径

您提供的Dropbox路径应该类似于:

/媒体/10506738_10150004552801856_220367501106153455_o.jpg

这将是相对于Dropbox根的路径。它没有驱动器号


您需要深入查看代码,以了解向Dropbox提供不正确路径类型的位置/原因。

问题在于Windows操作系统路径。我在Ubuntu中尝试了相同的设置。它在那里工作得完美无缺

关于发生此错误的原因,其他答案并不十分正确。dropbox存储对象后端使用django实用程序django.utils.\u os.safe\u join来验证目标操作系统的文件名。参见代码

即使您传递了upload_to参数,该参数提供了类似于/save/path的unix样式的路径,django实用程序也会确保该保存路径的根与操作系统的基本路径匹配:。dropbox SDK不喜欢在所需的存储路径(即C:/path/file)前加前缀的驱动器。名称不是dropbox的有效存储目录

要在Windows上运行此功能,请确保执行以下操作

首先,像这样修改存储后端完整路径方法或创建自己的子类

def _full_path(self, name):
    if name == '/':
        name = ''
    print('Root path in dropbox.storage : ', self.root_path)

    # If the machine is windows do not append the drive letter to file path
    if os.name == 'nt':
        final_path = os.path.join(self.root_path, name).replace('\\', '/')

        # Separator on linux system
        sep = '//'
        base_path = self.root_path

        if (not os.path.normcase(final_path).startswith(os.path.normcase(base_path + sep)) and
                os.path.normcase(final_path) != os.path.normcase(base_path) and
                os.path.dirname(os.path.normcase(base_path)) != os.path.normcase(base_path)):
            raise SuspiciousFileOperation(
                'The joined path ({}) is located outside of the base path '
                'component ({})'.format(final_path, base_path))
        # TODO Testing
        print('Full file path in storage.dropbox._full_path : ', final_path)
        return final_path

    else:
        return safe_join(self.root_path, name).replace('\\', '/')
其次,确保将内容和名称传递给模型文件字段。当我没有显式地传递文件内容并为上传的文件上下文命名某些内容时,我遇到了一些问题,并保留了文件名?。我像这样重新实现了我的模型保存方法

def save(self, *args, **kwargs):
    # Save file

    ## Save raw entry from user ##
    # Extract files contents
    try:
        uploaded_raw_entry = kwargs['upload_raw_entry']
    except KeyError:
        raise UploadError(('No file was passed from the admin interface. ' + 
            'Make sure a ContentFile was passed when calling this models save method'))

    # Test raw_directory_path TODO Remove after testing
    print('Raw entry name from model.save : ', raw_directory_path(self, uploaded_raw_entry.name))

    with uploaded_raw_entry.open(mode='rb') as f:
        raw_entry_content = f.read()
    raw_entry_file = ContentFile(content=raw_entry_content.encode('utf-8'),
                                 name=raw_directory_path(self, uploaded_raw_entry.name))

    # Save the content file into a model field
    raw_entry_file.open(mode='rb')
    self.raw_entry.save(raw_entry_file.name, raw_entry_file, save=False)
    raw_entry_file.close()

这在Windows上肯定是可行的,但需要额外的步骤:

我在Linux工作站上也遇到了这个问题-因此@greg的答案的等效Linux答案是在备份名称中添加一个/:

import sys, os
import dropbox
from dropbox.files import WriteMode
from dropbox.exceptions import ApiError, AuthError

# Add OAuth2 access token here.
TOKEN = '<your-token>'

data_path = './data_files'
filename   = 'my-file-backup.txt'
BACKUPPATH = "/"+filename  # <----- This should do the trick!

# Uploads contents of filename to Dropbox
def backup():
    current_file_path = os.path.join(data_path, filename)
    with open(current_file_path, 'rb') as f:
        print("Uploading " + filename + " to Dropbox as " + BACKUPPATH + "...")
        try:
            dbx.files_upload(f.read(), BACKUPPATH, mode=WriteMode('overwrite'))
        except ApiError as err:
            if (err.error.is_path() and
                    err.error.get_path().reason.is_insufficient_space()):
                sys.exit("ERROR: Cannot back up; insufficient space.")
            elif err.user_message_text:
                print(err.user_message_text)
                sys.exit()
            else:
                print(err)
                sys.exit()
因此,错误消息很容易混淆-问题中的文件名和路径不是您的本地文件名和路径,而是Dropbox远程文件名和路径

def save(self, *args, **kwargs):
    # Save file

    ## Save raw entry from user ##
    # Extract files contents
    try:
        uploaded_raw_entry = kwargs['upload_raw_entry']
    except KeyError:
        raise UploadError(('No file was passed from the admin interface. ' + 
            'Make sure a ContentFile was passed when calling this models save method'))

    # Test raw_directory_path TODO Remove after testing
    print('Raw entry name from model.save : ', raw_directory_path(self, uploaded_raw_entry.name))

    with uploaded_raw_entry.open(mode='rb') as f:
        raw_entry_content = f.read()
    raw_entry_file = ContentFile(content=raw_entry_content.encode('utf-8'),
                                 name=raw_directory_path(self, uploaded_raw_entry.name))

    # Save the content file into a model field
    raw_entry_file.open(mode='rb')
    self.raw_entry.save(raw_entry_file.name, raw_entry_file, save=False)
    raw_entry_file.close()
import sys, os
import dropbox
from dropbox.files import WriteMode
from dropbox.exceptions import ApiError, AuthError

# Add OAuth2 access token here.
TOKEN = '<your-token>'

data_path = './data_files'
filename   = 'my-file-backup.txt'
BACKUPPATH = "/"+filename  # <----- This should do the trick!

# Uploads contents of filename to Dropbox
def backup():
    current_file_path = os.path.join(data_path, filename)
    with open(current_file_path, 'rb') as f:
        print("Uploading " + filename + " to Dropbox as " + BACKUPPATH + "...")
        try:
            dbx.files_upload(f.read(), BACKUPPATH, mode=WriteMode('overwrite'))
        except ApiError as err:
            if (err.error.is_path() and
                    err.error.get_path().reason.is_insufficient_space()):
                sys.exit("ERROR: Cannot back up; insufficient space.")
            elif err.user_message_text:
                print(err.user_message_text)
                sys.exit()
            else:
                print(err)
                sys.exit()