简体   繁体   中英

Django Storages using s3boto ignoring MEDIA_URL

I am trying to use django-storages with s3boto in my app and trying to serve media and static files from s3.

I have the following settings in my settings file:

AWS_STORAGE_BUCKET_NAME = '<bucket_name>'
AWS_S3_ACCESS_KEY_ID = '<access_key>'
AWS_S3_SECRET_ACCESS_KEY = '<secret>'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = '<custom_storage_satic>'

MEDIAFILES_LOCATION = 'media'
DEFAULT_FILE_STORAGE = '<custom_storage_media>'

And my custom_storages.py is

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

When I create an image in django, instead of getting the relative path to my image starting with

image.url
'/media/image/<rest_of_the_path>.jpg'

I am getting the absolute url, which is something like

image.url
'https://<s3_bucket_name>.s3.amazonaws.com/media/image/original/'

When I use local storage instead of s3boto, it works as expected and gives me the relative path. Am I missing something here?

I struck the same issue when attempting to use the Imgix CDN for my S3 media (I suspect we're both using the same tutorial based on your use of the custom_storages.py override).

Here is an abridged version of the S3BotoStorage class in the django-storages framework. This excerpt highlights the important properties and methods for this issue, namely the custom-domain property.

class S3BotoStorage(Storage):
    location = setting('AWS_LOCATION', '')
    custom_domain = setting('AWS_S3_CUSTOM_DOMAIN')

    def url(self, name, headers=None, response_headers=None, expire=None):
        # Preserve the trailing slash after normalizing the path.
        name = self._normalize_name(self._clean_name(name))
        if self.custom_domain:
            return "%s//%s/%s" % (self.url_protocol, self.custom_domain, filepath_to_uri(name))

As you can see in the url method, a URL is generated to override the STATIC_URL and MEDIA_URL Django settings. Currently the domain of the URL is created with the AWS_S3_CUSTOM_DOMAIN setting, which is why you continue to see the static S3 URL for media files.

So first, in your Django settings file, add a setting describing your CDN's domain.

IMGIX_DOMAIN = 'example.imgix.net'

Then, similar to the override of the location property, add an override to the custom_domain property in your MediaStorage class.

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION
    custom_domain = settings.IMGIX_DOMAIN

Now the final URL to your media files should begin with your CDN's domain, followed by the relative path to your file on the S3 bucket.

如果从S3存储桶提供静态媒体,则必须使用绝对URL,因为媒体是从完全不同的服务器提供的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM