我在Django应用程序中使用S3Boto3Storage
包中的django-storages
存储后端。我使用后端处理S3中的大量文件。
从存储中读取文件时,后端会发出单独的HEAD
和GET
请求。我正在多次执行此操作,因此如果可能,我希望跳过HEAD
请求。
我的阅读操作与此类似:
class MyModel(models.Model):
img = FileField()
instance = MyModel.objects.filter().first()
instance.img.read()
我使用的是默认preload_metadata
标记,即False
。
是否有其他设置可以控制read方法的这种行为?
我的猜测是HEAD
请求在获取文件内容之前检查文件是否存在。因此,HEAD
调用可能会被try / except语句替换。但我无法弄清楚如何做到这一点。
答案 0 :(得分:0)
注意:以下解决方案不适用于生产,如果您在代码中看到此错误,则潜在客户会惩罚您:)
我的软件包版本较旧:
django-storages == 1.1.8
boto == 2.38.0
boto3 == 1.2.1
但是主要的想法(我希望)会被理解
在应用程序的某些“开始”级别(随您的喜好)上放置补丁(或者,如果愿意,可以扩展类)。
from storages.backends import s3boto
def monkey_init(self, name, mode, storage, buffer_size=None):
"""Only 'validate=mode != "rb"' was added in 'get_key' method's call"""
self._storage = storage
self.name = name[len(self._storage.location):].lstrip('/')
self._mode = mode
self.key = storage.bucket.get_key(self._storage._encode_name(name),
validate=mode != "rb")
if not self.key and 'w' in mode:
self.key = storage.bucket.new_key(storage._encode_name(name))
self._is_dirty = False
self._file = None
self._multipart = None
# for files larger than this.
if buffer_size is not None:
self.buffer_size = buffer_size
self._write_counter = 0
s3boto.S3BotoStorageFile.__init__ = monkey_init
在我的django-storages
版本中,对方法get_key
的调用未将validate
变量传递给它。除了明确重新定义__init__
方法外,我没有找到其他方法来强制/更改它。
PS:如果您的设置未在日志记录中包含明确的boto
部分-> GET / HEAD / etc的日志将不会显示。从boto要求。只需将boto
部分添加到日志记录设置部分即可。
'boto': {
'handlers': LOGGING_HANDLERS,
'level': 'DEBUG',
'propagate': False,
},