【问题标题】:Django Rest Framework serialized image returns absolute system url, and not amazon s3 urlDjango Rest Framework 序列化图像返回绝对系统 url,而不是 amazon s3 url
【发布时间】:2020-12-16 19:03:46
【问题描述】:

我目前在我的应用程序中使用 django-storages 来托管静态和媒体文件。我还在图像上传上使用 imagekit 来创建应用程序所需的图像的多个版本。

尝试序列化图像 url 时会出现问题。 DRF 返回一个 url,例如http://127.0.0.1:8000/media/CACHE/images/categories/tilbeh%C3%B8r/tilbehor/2fbf015bd21dba581f5d306ed4248b47.jpg,当打开它时,它返回一个完全空白的页面。我真正需要的是它返回“真实”的存储 url,例如https://domain.s3.amazonaws.com/static/media/CACHE/images/categories/tilbeh%C3%B8r/tilbehor/2fbf015bd21dba581f5d306ed4248b47.jpg.

S3 设置:

# aws settings
AWS_ACCESS_KEY_ID = 'secret'
AWS_SECRET_ACCESS_KEY = 'secret'
AWS_STORAGE_BUCKET_NAME = 'domain'
AWS_DEFAULT_ACL = 'public-read'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}
AWS_LOCATION = 'static'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
    # os.path.join(BASE_DIR, 'frontend/dist'),
]

STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIA_ROOT = 'static/media'
MEDIA_URL = '/media/'

models.py

class Category(models.Model):

    def upload_content_file_name(instance, filename):
        """
        Return the location of which to upload the file
        """
       
        return os.path.join('categories/%s/' % instance.name.lower(), filename)
    
    name = models.CharField(
        _('category name'), 
        max_length=255, 
        unique=False
    )
    ...
    image = models.ImageField(
        _('image'),
        upload_to=upload_content_file_name,
        help_text=_(
            'Category image, should only be used on top level parents!'
        ),
        blank=True, 
        null=True,

    )
    image_default = ImageSpecField(source='image', processors=[ResizeToFill(375, 375)], format='JPEG', options={'quality': 90})
    image_sm = ImageSpecField(source='image', processors=[ResizeToFill(640, 300)], format='JPEG', options={'quality': 90})
    image_md = ImageSpecField(source='image', processors=[ResizeToFill(768, 366)], format='JPEG', options={'quality': 90})
    image_lg = ImageSpecField(source='image', processors=[ResizeToFill(1024, 480)], format='JPEG', options={'quality': 90})
    image_xl = ImageSpecField(source='image', processors=[ResizeToFill(1280, 600)], format='JPEG', options={'quality': 90})
    ...

序列化器.py

class CategorySerializer(serializers.ModelSerializer):

    image_default = serializers.ImageField(read_only=True)
    image_sm = serializers.ImageField(read_only=True)
    image_md = serializers.ImageField(read_only=True)
    image_lg = serializers.ImageField(read_only=True)
    image_xl = serializers.ImageField(read_only=True)

    class Meta:
        model = Category
        fields = (
            ...
            'image',
            'image_default',
            'image_sm',
            'image_md',
            'image_lg',
            'image_xl',
        )

【问题讨论】:

    标签: django django-rest-framework django-storage


    【解决方案1】:

    上传的文件不是静态文件而是媒体文件, 请注意,您的媒体文件设置已关闭

    MEDIA_ROOT = 'static/media'
    MEDIA_URL = '/media/'
    

    当你将它们与静态的比较时

    STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
    STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
    

    【讨论】:

    • 我虽然对此有所了解,但是当试图将其更改为类似的东西时,我得到了django.core.exceptions.ImproperlyConfigured: runserver can't serve media if MEDIA_URL is within STATIC_URL.。你能指出我应该做的正确方向吗?
    • 您可能希望在您的存储桶中有 2 个名为 static 和 media 的相同级别的文件夹,而不是在另一个文件夹中,所以在 /static 和 /media 文件夹的行中而不是 /static/media @987654321 @
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2015-01-09
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多