gpt4 book ai didi

python - 在 Django 中通过哈希有效地保存文件

转载 作者:太空狗 更新时间:2023-10-30 02:10:08 25 4
gpt4 key购买 nike

我正在做一个 Django 项目。我希望用户能够做的是上传文件(通过表单),然后将文件本地保存到自定义路径并使用自定义文件名 - 它的哈希值。我能想到的唯一解决方案是使用我正在使用的 FileField 的“upload_to”参数。这意味着什么(我认为):

1) 将文件写入磁盘

2)计算哈希

3) 返回路径+散列作为文件名

问题是有两个写操作:一个是将文件从内存保存到磁盘计算hash,另一个是实际保存文件到指定位置。

有没有一种方法可以覆盖 FileField 的保存到磁盘方法(或者我在哪里可以准确找到幕后发生的事情)以便我基本上可以使用临时名称保存文件然后将其重命名为哈希,而不是它被保存了两次。

谢谢。

最佳答案

FileFieldupload_to 参数接受一个可调用对象,从中返回的字符串将加入您的 MEDIA_ROOT 设置以获取最终文件名(来自 documentation ):

This may also be a callable, such as a function, which will be called to obtain the upload path, including the filename. This callable must be able to accept two arguments, and return a Unix-style path (with forward slashes) to be passed along to the storage system. The two arguments that will be passed are:

  • instance: An instance of the model where the FileField is defined. More specifically, this is the particular instance where the current file is being attached. In most cases, this object will not have been saved to the database yet, so if it uses the default AutoField, it might not yet have a value for its primary key field.
  • filename: The filename that was originally given to the file. This may or may not be taken into account when determining the final destination path.

此外,当您访问 model.my_file_field 时,它会解析为 FieldFile 的一个实例,它就像一个文件。因此,您应该能够像下面这样编写 upload_to:

def hash_upload(instance, filename):
instance.my_file.open() # make sure we're at the beginning of the file
contents = instance.my_file.read() # get the contents
fname, ext = os.path.splitext(filename)
return "{0}_{1}{2}".format(fname, hash_function(contents), ext) # assemble the filename

替换为您要使用的适当哈希函数。根本不需要保存到磁盘(事实上,文件通常已经上传到临时存储,或者在较小文件的情况下只保存在内存中)。

你会像这样使用它:

class MyModel(models.Model):
my_file = models.FileField(upload_to=hash_upload,...)

我还没有测试过这个,所以你可能不得不戳一下读取整个文件的行(你可能只想散列文件的第一个 block 以防止恶意用户上传大量文件并导致 DoS攻击)。你可以得到第一个 block
instance.my_file.read(instance.my_file.DEFAULT_CHUNK_SIZE)

关于python - 在 Django 中通过哈希有效地保存文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31731470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com