2013-10-23 96 views
2

我的Django項目使用django_compressor通過django-storages軟件包通過boto在S3存儲區中存儲JavaScript和CSS文件。使用boto時爲Amazon S3密鑰設置cache-cotrol標題

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管理控制檯我看到等於在Cache-Control頭簽名已改爲%3D,如max-age%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) 

但顯示在亞馬遜S3管理控制檯這不會改變的元數據。

(更新The documentation for S3 metadata

你上傳的對象後,您不能修改對象元數據。修改對象元數據的唯一方法是使該對象的副本,並設置的元數據。欲瞭解更多您可以使用Amazon S3管理控制檯更新對象元數據,但在內部使用對象副本替換現有對象以設置元數據。

因此,也許這並不奇怪,我無法設置元數據。我認爲get_metadata僅在首先創建數據時使用。

末更新)

所以我的問題是,第一,我可以配置Django的存儲器,使其在第一時間正確地創建cache-control頭,二是set_metadata相同的元數據集作爲用S3管理控制檯查看的元數據,如果不是後者是什麼,以及如何以編程方式設置它?

回答

5

使用ASCII字符串作爲值爲我解決這個問題。

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

我試過了,它修復了這個問題。 – pdc

+0

你可以加一個更完整的例子嗎?我猜目前在哪裏粘貼你的解決方案。 –

+0

有關更正確的示例,我無法正確格式化... ' 'Cache-Control':'max-age = 604800',#60 x 60 x 24 x 7 = 1周 '內容 - 類型':CONTENT_TYPE, } K =密鑰(self.get_bucket()) k.key =文件名 k.set_contents_from_string(contents.getvalue(),標頭) 如果self.public:K .make_public() ' 爲我工作。看到我下面的完整答案... –

0

cache_control是key的屬性,而不是元數據的一部分。

所以設置緩存控制在一個桶中的所有對象,你可以這樣做:如果你想添加緩存控制,同時上載文件

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 
+0

這不行。正如更新後的問題所述,設置新的緩存控制標頭的唯一方法是「移動」文件。 – ehfeng

0

....

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) 

這博託2.32測試 - 2.40。

相關問題