Python и Django — как использовать в памяти и временные файлы

Мне нужно несколько примеров с файловыми операциями, использующими память и временные файлы.

Я много искал хороший пример/учебник, и я нашел только основные операции чтения/записи/добавления.

Мне нужно понять, как я могу прочитать в Django файл, который загружен (изображение) до завершения сохранения (сообщения).

Поскольку Django — это Python, я думаю, что лучше сначала разобраться в python.

Я проверил документацию/примеры Django, но это не очень ясно, поэтому мне нужно сначала понять в Python, а затем в Django, как работают операции, а не просто копировать и вставлять.

Я знаю, как использовать ImageFields, загружать операции по умолчанию, меня интересует только использование в памяти и временных файлов.

Я хочу использовать это в сочетании с функцией кадрирования. Таким образом, пользователь может загрузить 1, 2, 3... изображения, и с помощью скрипта обрезки javascript я получаю координаты в скрытом поле. После того, как javascript смоделировал кадрирование, я показываю пользователю миниатюру с кадрированием, как будет выглядеть соотношение

Пользователь может передумать и может отредактировать/обновить или удалить файл перед сохранением.

Теперь в зависимости от размера файла его можно хранить в памяти или записывать.


person user3541631    schedule 24.08.2017    source источник
comment
Я чувствую, что вы хотите знать, как загрузить изображение на сервер django. это правильно ?   -  person Vasif    schedule 24.08.2017
comment
Я знаю, как загрузить изображение, используя ImageField и т. д., мне нужно что-то конкретное относительно памяти и временных файлов.   -  person user3541631    schedule 24.08.2017
comment
я попытался записать лучшее, что я могу получить из вашего вопроса. Не стесняйтесь добавлять то, что вы ищете, в качестве комментария.   -  person Vasif    schedule 24.08.2017
comment
Было бы полезно, если бы вы сказали немного больше о том, что именно вы хотите сделать с файлом в памяти/temp. Все в Django построено поверх собственной библиотеки ввода-вывода Python. docs.python.org/3/tutorial/   -  person Jarek.D    schedule 24.08.2017
comment
Хорошо, теперь я вижу, чего вы пытаетесь достичь. В этом случае вам не нужно отправлять файл на сервер. Обрезка и предварительный просмотр на клиенте и сохранение на сервер только тогда, когда пользователь принимает обрезку   -  person Jarek.D    schedule 24.08.2017
comment
Урожай будет сделан с подушкой (несколько типов культур) позади. Я не работаю с фронтендом из-за нескольких культур, и мне нужно, чтобы он работал в IE9.   -  person user3541631    schedule 24.08.2017
comment
Если вы хотите использовать Pillow, вы должны загрузить файл как обычно, прочитать его из запроса в соответствии с предложением из моего ответа ниже, создать миниатюры, сохранить миниатюры и показать их пользователю.   -  person Jarek.D    schedule 24.08.2017


Ответы (4)


Когда файл загружен, Django выполнит одно из двух действий: сохранит его в памяти, если файл небольшой (‹ 2 МБ в последний раз, когда я проверял), или сохранит его как временный файл на диске, если он большой. Это поведение настраивается с помощью параметра FILE_UPLOAD_HANDLERS. Таким образом, ваш веб-сервер и Django позаботятся о фактической загрузке и хранении, но ваша задача — обработать файл до завершения запроса, иначе файл будет удален.

Загруженные файлы доступны через свойство request.FILES. Каждый ключ в FILES будет соответствовать имени входного файла на вашем <form>. Значение представляет собой объект UploadedFile, представляющий собой поток, который вы можете использовать для чтения данных файла.

Например, у вас есть <input name="img" type="file" />, и вы хотите определить, является ли изображение полностью белым. Вам не нужно хранить файл для этого, вам просто нужно загрузить его в память, обработать его, чтобы получить результат, а затем позволить ему быть отброшенным.

from PIL import Image

def some_view(request):
    if request.method == 'POST':
        img_file = request.FILES['img']

        if img_file.size > 2000000:
            return HttpResponseBadRequest()

        img = Image.open(img_file)

        # analyze the image...

Другая возможность заключается в том, что кто-то загружает довольно большой файл резервной копии (скажем, 2 ГБ), и вам нужно его где-то сохранить. По сути, это то же самое, за исключением того, что мы читаем файл в память порциями, а затем записываем каждую порцию на диск куда-то еще, чтобы он сохранялся после завершения запроса.

def some_view(request):
    if request.method == 'POST':
        backup_file = request.FILES['backup_file']
        with open('some/file/name.bak', 'wb+') as destination:
            for chunk in backup_file.chunks():
                destination.write(chunk)

        # file is saved

Когда запрос завершен, загруженный файл сохраняется по адресу some/file/name.bak.

Будь то в памяти или во временном файле, обычно не важно, потому что интерфейс тот же. Вы можете прочитать временный файл так же, как вы можете прочитать файл в памяти.

person mindcruzer    schedule 24.08.2017

Вы можете указать, какой обработчик загрузки используется для формы Django: https://docs.djangoproject.com/en/1.11/ref/files/uploads/#module-django.core.files.uploadhandler

Есть два встроенных варианта:

Похоже, что Django работает, просматривая список всех обработчиков загрузки: https://docs.djangoproject.com/en/1.11/topics/http/file-uploads/#upload-handlers

Для каждого обработчика загрузки он будет проверять определенное условие, и если это условие истинно, он активирует и использует этот обработчик загрузки.

Например, InMemoryUploadHandler активируется и используется, когда размер файлов меньше определенного. TemporaryFileUploadHandler используется, когда файлы очень большие.

Вы сможете получить доступ к данным и файлам из объекта request.

person Community    schedule 24.08.2017

Если вы ищете специфичный для Python (не Django), то, похоже, вас может заинтересовать модуль tempfile:

https://docs.python.org/3/library/tempfile.html

Адаптация примера из документа выше:

import tempfile

fp = tempfile.TemporaryFile()
fp.write(b'Hello world!')
# Closing automatically deletes the tempfile
fp.close()

Вы можете видеть, что это работает очень похоже на общие операции чтения/записи файлов.

person Proto    schedule 24.08.2017
comment
Сначала я пытаюсь понять, как работает Python, затем перехожу к Django. - person user3541631; 24.08.2017

Если я правильно понимаю, вы ищете способ получить доступ к загруженному файлу до его сохранения с помощью instance.save() или аналогичного.

Если это так, вы можете попытаться прочитать файл непосредственно из запроса:

if my_form.is_valid():
    data = request.FILES['myfile'].read()
person Jarek.D    schedule 24.08.2017