Using Cloudfront with Django S3Boto

后端 未结 2 1208
-上瘾入骨i
-上瘾入骨i 2021-01-30 23:52

I have successfully set up my app to use S3 for storing all static and media files. However, I would like to upload to S3 (current operation), but serve from a cloudfront instan

2条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-31 00:07

    Your code is almost complete except you are not adding your cloudfront domain to STATIC_URL/MEDIA_URL and your custom storages.

    In detail, you must first install the dependencies

    pip install django-storages-redux boto
    

    Add the required settings to your django settings file

    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'
    

    Your custom storages need some modification to present the cloudfront domain for the resources, instead of the S3 domain:

    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)
    

    And that is all you need, assuming your bucket and cloudfront domain are correctly linked and the user's AWS_ACCESS_KEY has access permissions to your bucket. Additionally, based on your use case, you may wish to make your s3 bucket items read-only accessible by everyone.

提交回复
热议问题