Django文件存储:为文件名添加密码

时间:2017-01-20 17:24:05

标签: django django-storage

我们使用Python Django。

我想以下列方式存储用户上传的文件:

/<INTEGER>/<HASH>/<FILE>

<INTEGER>是一个子文件夹,意味着包含最多1000个文件。

<HASH>是每个文件的密码,用于防止黑客从我们的HTTPS服务器下载某人的其他文件。

<FILE>是文件名。

如何编写实现此功能的Django存储?

首先,我可以从django.core.files.storage.FileSystemStorage派生我的课程,还是需要直接从django.core.files.storage.Storage派生?

其次,我应该覆盖哪些方法?我应该覆盖save吗?似乎是的,因为最好只在保存时生成哈希,但我不确定我能在save中做我需要的东西。覆盖_save怎么样?另外:覆盖get_available_name和/或generate_filename的内容是什么?它们似乎不能完全满足我的需求,因为最好只在实际保存文件时生成哈希,而不仅仅是在考虑其名称时。

那么,该怎么办?

3 个答案:

答案 0 :(得分:0)

我想你可以拥有自己的函数来处理你想要创建文件夹结构的方式,你可以将models.py作为
attachment = models.FileField(upload_to = change_file_path,blank = True,null =真正)  
其中change_file_path是用于创建所需文件夹结构的自定义函数

答案 1 :(得分:0)

使用storageupload_to参数设置上传目录。更多信息FileField django docs

这里我使用uuid作为<HASH>您可以使用自己的哈希生成器进行更改),max_num为<integer>,并且Django模型中的senfile为<FILE>

models.py

from django.core.files.storage import FileSystemStorage
import uuid

storeFile = FileSystemStorage(location='SensitiveFiles/')

def content_file_upload(instance, filename):
    return '{0}/{1}/{2}'.format(instance.max_num,str(uuid.uuid4()), filename)

class SensitiveFiles(models.Model):
    user = models.ForeignKey(User)
    senfile = models.FileField(storage=storeFile,upload_to=content_file_upload,validators=[validation_for_max_num_files])
    max_num=models.IntegerField(default=1000)

    def get_file_url(self):
        return self.senfile.url

创建验证器以检查上传目录中的当前文件数。

答案 2 :(得分:0)

我会在generate_filename中找到django.core.files.storage.FileSystemStorage。我认为它更合适,因为我在get_available_name中仍然有一个很好的安全垫。 在没有保存文件的情况下,我也不担心获取文件名,只需要确保哈希生成足够便宜。

# settings.py

DEFAULT_FILE_STORAGE = 'app.storage.CustomStorage'
# app/storage.py

from datetime import datetime
import hashlib
import random

from django.core.files.storage import FileSystemStorage


class CustomStorage(FileSystemStorage):
    def generate_filename(self, filename):
        # implement smarter hash creation method here
        some_hash = hashlib.md5('{}-{}'.format('filename', datetime.now().isoformat())).hexdigest()

        return '{0}/{1}/{2}'.format(random.randint(0, 1000), some_hash, filename)