【问题标题】:Using Cloudfront with Django S3Boto将 Cloudfront 与 Django S3Boto 一起使用
【发布时间】:2015-07-11 12:49:45
【问题描述】:

我已成功将我的应用设置为使用 S3 存储所有静态和媒体文件。但是,我想上传到 S3(当前操作),但从我设置的云端实例提供服务。我已尝试将设置调整为 cloudfront url,但它不起作用。请问如何上传到 S3 并从 Cloudfront 提供服务?

设置

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

DEFAULT_FILE_STORAGE = 'app.custom_storages.MediaStorage'
STATICFILES_STORAGE = 'app.custom_storages.StaticStorage'

STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'

STATIC_URL = "https://s3-eu-west-1.amazonaws.com/app/%s/" % (STATICFILES_LOCATION)
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)

custom_storages.py

from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

【问题讨论】:

  • 您是否有其他信息为什么它不起作用?有任何错误信息吗?
  • 这里已经回答了:stackoverflow.com/questions/8688815/…
  • 如果它对任何人有帮助,我还必须为 collectstatic 添加设置 AWS_DEFAULT_ACL = '' 才能工作,而不是返回 403。

标签: python django


【解决方案1】:

您的代码几乎完成了,除了您没有将您的云端域添加到 STATIC_URL/MEDIA_URL 和您的自定义存储。

具体来说,必须先安装依赖项

pip install django-storages-redux boto

将所需的设置添加到您的 django 设置文件中

INSTALLED_APPS = (
    ...
    'storages',
    ...
)

AWS_STORAGE_BUCKET_NAME = 'mybucketname'
AWS_CLOUDFRONT_DOMAIN = 'xxxxxxxx.cloudfront.net'
AWS_ACCESS_KEY_ID = get_secret("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = get_secret("AWS_SECRET_ACCESS_KEY")

MEDIAFILES_LOCATION = 'media'
MEDIA_ROOT = '/%s/' % MEDIAFILES_LOCATION
MEDIA_URL = '//%s/%s/' % (AWS_CLOUDFRONT_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'app.custom_storages.MediaStorage'

STATICFILES_LOCATION = 'static'
STATIC_ROOT = '/%s/' % STATICFILES_LOCATION
STATIC_URL = '//%s/%s/' % (AWS_CLOUDFRONT_DOMAIN, STATICFILES_LOCATION)
STATICFILES_STORAGE = 'app.custom_storages.StaticStorage'

您的自定义存储需要进行一些修改以显示资源的云端域,而不是 S3 域:

from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
"""uploads to 'mybucket/static/', serves from 'cloudfront.net/static/'"""
    location = settings.STATICFILES_LOCATION

    def __init__(self, *args, **kwargs):
        kwargs['custom_domain'] = settings.AWS_CLOUDFRONT_DOMAIN
        super(StaticStorage, self).__init__(*args, **kwargs)

class MediaStorage(S3BotoStorage):
"""uploads to 'mybucket/media/', serves from 'cloudfront.net/media/'"""
    location = settings.MEDIAFILES_LOCATION

    def __init__(self, *args, **kwargs):
        kwargs['custom_domain'] = settings.AWS_CLOUDFRONT_DOMAIN
        super(MediaStorage, self).__init__(*args, **kwargs)

这就是您所需要的一切,假设您的存储桶和云端域已正确链接并且用户的 AWS_ACCESS_KEY 具有对您的存储桶的访问权限。此外,根据您的用例,您可能希望将您的 s3 存储桶项设置为可供所有人只读访问。

【讨论】:

  • 很好,简洁的答案。
  • 请问为什么首选MEDIA_URL = '//%s/%s/ 而不是MEDIA_URL='http://%2/%s/
  • @eugene 通过省略协议说明符(// 而不是 http://https://),您可以让浏览器根据包含文档的方式自动选择正确的协议(http 或 https)已加载。因此,您可以同时提供安全和非安全页面,并使静态链接保持不变。例如:stackoverflow.com/questions/4831741/…
  • STATIC_ROOTMEDIA_ROOT 似乎没有与 django-storages 一起使用。
  • @Mark Galloway 非常感谢。
【解决方案2】:

我遇到了类似的问题,只是将 AWS_S3_CUSTOM_DOMAIN 设置为 Django 的 settings.py 中的 Cloudfront url 对我有用。您可以查看代码here

【讨论】:

  • 您是否需要在云端启用 PUT DELETE 等选项?此外,您的链接已失效。
猜你喜欢
  • 2015-11-11
  • 2012-04-06
  • 2020-11-29
  • 2016-03-25
  • 2018-04-13
  • 2022-12-16
  • 2021-06-18
  • 2013-06-19
  • 2015-11-24
相关资源
最近更新 更多