2

我正在更新我的应用程序的依赖项。我对 requirements.txt 进行了以下更改:

  • boto:升级到 2.34.0
  • django-pipeline:升级到 1.4.2
  • django-require:升级到 1.0.6
  • django-storages:最新版本(1.1.8)

现在,当我尝试在我的 S3 存储桶中运行 collectstatic 时,我收到以下错误:

boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidArgument</Code><Message></Message><ArgumentName>x-amz-acl</ArgumentName>
<ArgumentValue>/tmp/tmpDyVin1</ArgumentValue><RequestId>xxx</RequestId>
<HostId>yyy</HostId></Error>

毫不奇怪,因为显然/tmp/tmpDyVin1不是x-amz-acl 的有效值

问题源于指定我自己的类来处理结合了 Boto、Require 和 Pipeline 的静态文件:

设置.py

STATICFILES_STORAGE = 'myapp.storage.OptimizedS3BotoStorage'

存储.py

from pipeline.storage import PipelineMixin
from require.storage import OptimizedFilesMixin
from storages.backends.s3boto import S3BotoStorage

class ReleaseVersionCachedFilesMixin(CachedFilesMixin):

    def hashed_name(self, name, content=None):
        ...

class OptimizedS3BotoStorage(PipelineMixin, OptimizedFilesMixin, ReleaseVersionCachedFilesMixin, S3BotoStorage):
    pass

这与所有这些模块的旧版本完美一致。挖掘新代码,我发现问题在于与这三个的交互:

  • 调用时S3BotoStorage.__init__(),第一个参数 ,acl作为此 tmp 目录的值传入。这会覆盖之前的值public-read并导致上述问题。
  • __init__()例程由 调用CachedFilesMixin.__init__(),它接收args = ('/tmp/tmpnNUVD9',).
  • __init__()由 调用PipelineMixin.__init__(),它执行以下操作:

def __init__(self, location=None, *args, **kwargs): if not settings.PIPELINE_ENABLED and location is None: location = tempfile.mkdtemp() super(PipelineMixin, self).__init__(location, *args, **kwargs)

因此,问题在于 Pipelinelocation作为第一个参数传入,该参数向下传播并成为acl.

4

1 回答 1

2

看起来解决这个令人讨厌的问题的方法只是将 PipelineMixin 移动到我的自定义存储类中的参数列表的末尾,但这会破坏 r.js 优化器。解决方案是将此PIPELINE_ENABLED标志设置为True.

(文档说这个标志默认为not settings.DEBUG,但这对于您的环境可能不是一个有意义的依赖项。该标志PipelineMixin直到 1.4 才以这种方式使用,但它没有记录在升级到 1.4 的指令中。)

于 2015-01-04T22:41:46.420 回答