Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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
Django 使用boto为Amazon S3密钥设置缓存控制头时出现问题_Django_Amazon S3_Boto - Fatal编程技术网

Django 使用boto为Amazon S3密钥设置缓存控制头时出现问题

Django 使用boto为Amazon S3密钥设置缓存控制头时出现问题,django,amazon-s3,boto,Django,Amazon S3,Boto,我的Django项目使用Django_压缩器通过Django storages包的boto将JavaScript和CSS文件存储在S3存储桶中 django存储相关配置包括 if 'AWS_STORAGE_BUCKET_NAME' in os.environ: AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME'] AWS_HEADERS = { 'Cache-Control': 'max-a

我的Django项目使用Django_压缩器通过Django storages包的boto将JavaScript和CSS文件存储在S3存储桶中

django存储相关配置包括

if 'AWS_STORAGE_BUCKET_NAME' in os.environ:
    AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']
    AWS_HEADERS = {
        'Cache-Control': 'max-age=100000',
        'x-amz-acl': 'public-read',
    }
    AWS_QUERYSTRING_AUTH = False

    # This causes images to be stored in Amazon S3
    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

    # This causes CSS and other static files to be served from S3 as well.
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    STATIC_ROOT = ''
    STATIC_URL = 'https://{0}.s3.amazonaws.com/'.format(AWS_STORAGE_BUCKET_NAME)

    # This causes conpressed CSS and JavaScript to also go in S3
    COMPRESS_STORAGE = STATICFILES_STORAGE
    COMPRESS_URL = STATIC_URL
除了在S3管理控制台中访问对象时,我看到
缓存控制
标题中的等号已更改为
%3D
,如
最大年龄%3D100000
,这将停止缓存工作外,其他操作都有效

我写了一个小脚本,试图按照以下思路解决这个问题:

max_age = 30000000
cache_control = 'public, max-age={}'.format(max_age)

con = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
bucket = con.get_bucket(settings.AWS_STORAGE_BUCKET_NAME)
for key in bucket.list():
    key.set_metadata('Cache-Control', cache_control)
但这不会更改AmazonS3管理控制台中显示的元数据

(更新)说

上载对象后,无法修改对象元数据。修改对象元数据的唯一方法是复制对象并设置元数据。有关详细信息,请转到Amazon Simple Storage Service API参考中的PUT object-copy。您可以使用Amazon S3管理控制台更新对象元数据,但不能在内部更新创建对象副本以替换现有对象以设置元数据

因此,我不能设置元数据也就不足为奇了。我假设
get\u metadata
仅在创建数据时使用

结束更新)


因此,我的问题是,首先,我是否可以配置django存储,以便它首先正确地创建
缓存控制
头,然后,使用
set\u metadata
设置的元数据是否与使用S3管理控制台查看的元数据相同?如果不是,后者是什么?我如何通过编程进行设置?

使用ASCII字符串作为值为我解决了这一问题

AWS_HEADERS = {'Cache-Control': str('public, max-age=15552000')}

cache_控件是key的属性,而不是元数据的一部分

因此,要为bucket中的所有对象设置缓存控制,可以执行以下操作:

s3_conn = S3Connection(AWS_KEY, AWS_SECRET)

bucket = s3_conn.get_bucket(AWS_BUCKET_NAME)

bucket.make_public()

for key in bucket.list():
    key = bucket.get_key(key.name)
    key.cache_control = 'max-age=%d, public' % (3600 * 24 * 360 * 2)
    print key.name + ' ' +  key.cache_control

如果要在上载文件时添加缓存控制

 headers = {
    'Cache-Control':'max-age=604800', # 60 x 60 x 24 x 7 = 1 week
    'Content-Type':content_type,
  }

  k = Key(self.get_bucket())
  k.key = filename
  k.set_contents_from_string(contents.getvalue(), headers)
  if self.public: k.make_public()

如果要将缓存控制添加到现有文件

for key in bucket.list():
  print key.name.encode('utf-8')
  metadata = key.metadata
  metadata['Cache-Control'] = 'max-age=604800' # 60 x 60 x 24 x 7 = 1 week
  key.copy(AWS_BUCKET, key, metadata=metadata, preserve_acl=True)

这在boto 2.32-2.40中进行了测试。

这不起作用。设置新的缓存控制头的唯一方法是“移动”文件,正如更新的问题所说。您可以添加一个更完整的例子吗?我正在猜测你的解决方案现在应该粘贴到哪里。关于一个更完整的例子,我无法正确格式化…`headers={'Cache Control':'max-age=604800',#60 x 60 x 24 x 7=1周'内容类型':内容类型,}k=Key(self.get_bucket())k.Key=filename k.set_contents_from_string(contents.getvalue(),headers),如果self.public:k.make_public()`对我有效。请参阅下面我的完整答案…我使用Python2.7,不清楚这如何避免URL编码器,但很好地找到了。“-”现在被删除,仅限于驼峰大小写CacheControl','ContentType'