python - Django-storages S3Boto3Storage 在读取时发出 HEAD 和 GET 请求

标签 python django amazon-s3 boto3 python-django-storages

我在 Django 应用程序中使用 django-storages 包中的 S3Boto3Storage 存储后端。我使用后端处理 S3 中的大量文件。

从存储中读取文件时,后端会发出单独的 HEADGET 请求。我多次执行此操作,因此我希望尽可能跳过 HEAD 请求。

我的读取操作看起来与此类似:

class MyModel(models.Model):
    img = FileField()

instance = MyModel.objects.filter().first()
instance.img.read()

我正在使用默认的 preload_metadata 标志,即 False

是否有其他设置可以控制 read 方法的这种行为?

我的猜测是 HEAD 请求在获取文件内容之前检查文件是否存在。所以也许可以用 try/except 语句替换 HEAD 调用。但我不知道该怎么做。

最佳答案

注意:以下解决方案不适用于生产,如果在您的代码中看到此内容,您的领导会惩罚您 :)

我的包版本是旧的:
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/等的日志将不会显示。来自博托的要求。只需将 boto 部分添加到日志设置部分即可。

'boto': {
    'handlers': LOGGING_HANDLERS,
    'level': 'DEBUG',
    'propagate': False,
},

关于python - Django-storages S3Boto3Storage 在读取时发出 HEAD 和 GET 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47674464/

相关文章:

Python 初学者 - 如何从另一个列表生成列表和频率

python - 加载 Jupyter Notebook 扩展时出错

python - 在 Virtualenv 中使用 Python 的 Pip

python - IntegrityError Question_question.pub_date 不能为 NULL

python - Django : python manage. py runserver(多个错误)

django - 如何使 Django 表单在验证失败后保留文件

python - Django 单元测试模拟

java - aws s3 cp > 如何在 aws Java SDK 中实现带有分段复制的 cp 命令

python - 如何检查我上传的文件是否为 "multipart"?

python - 在 AWS 中标记 s3