2017-01-20 5 views
0

Мы используем Python Django.Хранилище файлов 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? Они, похоже, не совсем адаптированы к моим потребностям, потому что было бы лучше генерировать хеш только при фактическом сохранении файла, а не только при рассмотрении его имени.

Итак, что делать?

+0

Я бы перефразировать '' для '' , как его сбивает с толку и вид красного флага :) – petkostas

+2

Вы, вероятно, не хотите сделать это для всех загрузок по всему миру только для чувствительных, и вы можете сделать это на основе поля, написав свой собственный ['upload_to'] (https://docs.djangoproject.com/en/1.10/ref/models/fields/#django .db.models.FileField.upload_to). – Anonymous

+0

@ Анонимный Я хочу, чтобы ** все ** загружались, чтобы быть защищенным, помещая их в каталог с секретным именем. – porton

ответ

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) 
0

Я думаю, у вас может быть собственная функция для обработки того, как вы хотите создать структуру папок, и вы можете иметь в models.py как
attachment = models.FileField (upload_to = change_file_path, blank = True, null = True)
где change_file_path ваша пользовательская функция, чтобы создать нужную структуру папок

+0

Это не решение: 1. хеш - это уникальная строка, сгенерированная * при загрузке файла *, индивидуальная для каждого файла. 2. Он должен работать для ** каждого ** 'FileField', который не устанавливается индивидуально для каждого файла. Поэтому мне нужно создать пользовательское хранилище, а не просто установить 'upload_to' вручную! – porton

0

Используя оба storage и upload_to аргументы для настройки загрузки информации directory.More FileField django docs

Здесь я использую UUID, как <HASH> (вы могли бы тя Нге используя свой собственный хэш-генератор), MAX_NUM является <integer> и senfile является <FILE> в модели Django

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 

Создайте валидатор для проверки текущего количества файлов в каталоге загруженного.

+0

Это не решение: 1. хэш - это уникальная строка, сгенерированная * при загрузке файла *, для каждого файла. 2. Он должен работать для ** каждого ** 'FileField', который не устанавливается индивидуально для каждого файла. Поэтому мне нужно создать пользовательское хранилище, а не просто установить 'upload_to' вручную! – porton