python - django-storages dropbox.stone_validators.ValidationError

标签 python mysql json django dropbox

我正在尝试使用保管箱作为媒体存储。我正在尝试通过 django-storages 来实现。

settings.py

DEFAULT_FILE_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DROPBOX_OAUTH2_TOKEN = 'token'
DROPBOX_ROOT_PATH = '/media/'

模型.py

logo = models.ImageField(upload_to=r'logo/%Y/%m/')
image = models.ImageField(upload_to=r'photos/%Y/%m/',
 help_text='Image size: Width=1080 pixel. Height=1920 pixel',)

错误

请求方法:|发布

请求网址:| http://127.0.0.1:8000/add

Django 版本: | 2.1.8

异常类型:|验证错误

异常值:| 'D:/media/10506738_10150004552801856_220367501106153455_o.jpg' 不匹配模式 '(/(.|[\r\n])|id:.)|(rev:[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 存储对象后端使用 django 实用程序 (django.utils._os.safe_join) 来验证目标操作系统的文件名。查看代码 here

即使您传递了 upload_to 参数,它给出了一个 unix 风格的路径(类似于/save/path),django 实用程序确保该保存路径的根目录与操作的基本路径相匹配系统 :(。Dropbox SDK 不喜欢以所需保存路径为前缀的驱动器(又名 C:/path/file.name 不是 Dropbox 的有效保存目录)。

要在 Windows 上运行此功能,请确保您做几件事

首先,像这样修改存储后端_full_path 方法(或创建自己的子类)。

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('\\', '/')

其次,确保将内容和名称传递给模型 FileField。当我没有明确传递文件内容和名称时,我遇到了麻烦(关于保留文件名的上传文件上下文?)。我像这样重新实现了我的模型保存方法

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 中绝对可行,但需要额外的步骤:)

关于python - django-storages dropbox.stone_validators.ValidationError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55587089/

相关文章:

python - Pandas Python : why does np. round() 3.601626 到 2 dp 返回 3.6?

python - Python 重载父类字段

创建表中的 MySQL 命名空间

mysql - 外键到非候选键以及删除级联

javascript - 为什么不是我所有的正值都是绿色而负值不是红色?

Python3.x,如何聚焦新打开的网页

python - 如何找到Python库的安装路径?

mysql - 选择两个表并求和列值

json - Json 数组的 Avro 模式

javascript - Lodash 更新另一个数组 Chain/Map 中的元素值