django-storages + sorl_thumbnail + S3 不能很好地协同工作(URL 不匹配)
Posted
技术标签:
【中文标题】django-storages + sorl_thumbnail + S3 不能很好地协同工作(URL 不匹配)【英文标题】:django-storages + sorl_thumbnail + S3 not working well together (URLs mismatch) 【发布时间】:2012-09-21 11:57:28 【问题描述】:我将 django-storages 和 sorl_thumbnail 一起使用,并且我将 Amazon S3 用于静态和媒体文件。我正在使用一个带有 2 个文件夹的存储桶,1 个用于静态文件夹,1 个用于媒体文件夹。
这是我的配置:
MEDIA_ROOT = '/media/'
MEDIA_URL = 'https://s3.amazonaws.com/my-bucket/media/'
STATIC_ROOT = '/static/'
STATIC_URL = 'https://s3.amazonaws.com/my-bucket/static/'
AWS_STORAGE_BUCKET_NAME = 'my-bucket'
DEFAULT_FILE_STORAGE = 'my_lib.s3utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 'my_lib.s3utils.StaticRootS3BotoStorage'
MediaRootS3BotoStorage
和 StaticRootS3BotoStorage
定义如下:
StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static')
MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media')
当我使用 sorl_thumbnail 时,生成的缩略图位于正确的目录中:https://s3.amazonaws.com/my-bucket/media/cache
但是当 sorl_thumbnail 试图检索已经存在的缩略图时,生成的 URL 是:https://s3.amazonaws.com/my-bucket/cache
,您会注意到 @987654327 @文件夹被省略。
你知道我该如何解决这个问题吗?
我知道我可以只使用 django-storages 并将我的静态和媒体文件都混合在我的存储桶中,但这对我来说有点太脏了 :)
谢谢!
【问题讨论】:
【参考方案1】:您是否尝试将 THUMBNAIL_PREFIX 设置为 media/cache/?
http://sorl-thumbnail.readthedocs.org/en/latest/reference/settings.html#thumbnail-prefix
【讨论】:
是的,我已经试过了,谢谢。但它也不起作用,问题将是相同的,例如如果我在推送文件时设置/media/cache
,则url将为/media/media/cache
,检索时使用魔杖/media/cache
【参考方案2】:
我遇到了同样的问题,但我找到了解决方法。
我将我的DEFAULT_FILE_STORAGE
设置回storages.backends.s3boto.S3BotoStorage
,这样,当它寻找cache/
时它不会错过,我仍然可以将我的所有文件上传到media/
,并且python manage.py collectstatic
仍然有效正确,因为我仍然将其设置为StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static')
。
希望这对您有所帮助,因为这个问题让我发疯了。
【讨论】:
感谢您的帮助!但是当我使用这些设置时,我的结果是静态文件进入 S3 上的 /static/ 文件夹,但所有上传的文件都在根文件夹中,它们不进入 /media/。有什么想法吗? 抱歉回复晚了,但请确保在您的模型中使用UPLOAD_TO='media/'
。这应该把你上传的文件放在你想要的地方。
是的,我猜你在做,但我不希望这样做,否则它只会破坏 django 工作的目的:) 无论如何谢谢!
@e-Jah 你找到解决方案了吗,因为我面临同样的问题
@SalmaHamed:不幸的是,我的解决方案是切换到我自己的服务器,它解决了很多麻烦!【参考方案3】:
我能够通过如下定义 MediaRootS3BotoStorage 和 StaticRootS3BotoStorage 使其工作:
from storages.backends.s3boto import S3BotoStorage
from django.conf import settings
class StaticRootS3BotoStorage(S3BotoStorage):
"""
Storage for static files.
"""
def __init__(self, *args, **kwargs):
kwargs['location'] = 'static'
super(StaticRootS3BotoStorage, self).__init__(*args, **kwargs)
class MediaRootS3BotoStorage(S3BotoStorage):
"""
Storage for uploaded media files.
"""
def __init__(self, *args, **kwargs):
kwargs['location'] = 'media'
super(MediaRootS3BotoStorage, self).__init__(*args, **kwargs)
此链接可能会有所帮助https://github.com/jamstooks/django-s3-folder-storage
【讨论】:
上述每个__init__()
方法上的super()
方法调用了错误的类。它们应该是:super(StaticRootS3BotoStorage, self).__init__(*args, **kwargs)
和 super(MediaRootS3BotoStorage, self).__init__(*args, **kwargs)
【参考方案4】:
发现sorl-thumbnail
正在使用STATIC_URL
返回缓存的KV
图像url
(在创建初始缩略图后的下一个请求上)。出现MEDIA_URL
没有影响。
不是最好的解决方案。添加了S3
路由规则。
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>cache/</KeyPrefixEquals>
</Condition>
<Redirect>
<ReplaceKeyPrefixWith>media/cache/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
【讨论】:
【参考方案5】:我遇到了同样的问题,Salma Hamed 的解决方案结果证明对我来说是正确的。
在我们有之前
StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static')
MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media')
这导致我们的 thumbnail_kvstore 表中的“存储”值错误。此 lambda 定义不会创建新类,因此 type(StaticRootS3BotoStorage()) 返回写入表中的“storages.backends.s3boto.S3BotoStorage”。因为这些 'storage' 值用于稍后实例化存储以便在显示时获取图像 URL,这导致 S3BotoStorage() 用于此目的。所以'位置'论点丢失了。
Salma Hamed 将这些自定义存储定义为类的解决方案解决了这个问题。
谢谢!
【讨论】:
你还记得你在哪里学会使用lambda: S3BotoStorage(location='static')
之前的解决方案吗?我想发表评论或更正。【参考方案6】:
IDK 为什么但 @SalmaHamed 的解决方案对我不起作用(可能是因为 django 版本的变化或其他原因)。相反,我将:MediaRootS3BotoStorage = lambda: S3Boto3Storage(location='media')
替换为: class MediaRootS3BotoStorage(S3Boto3Storage): location = 'media'
【讨论】:
以上是关于django-storages + sorl_thumbnail + S3 不能很好地协同工作(URL 不匹配)的主要内容,如果未能解决你的问题,请参考以下文章
Django-storage - 如何在上传前检查文件大小?
Django:使用 django-storage 从 S3 创建 zipfile
使用 azure 作为 Django 的存储后端(使用 django-storages)
django-storages + sorl_thumbnail + S3 不能很好地协同工作(URL 不匹配)
保存模型字段时的 Django-Storages ('`data` must be bytes, received', <class 'str'>)