загрузка нескольких файлов с использованием одного и того же имени входа в django

У меня проблемы с загрузкой нескольких файлов с одинаковым входным именем:

<input type=file name="file">
<input type=file name="file">
<input type=file name="file">

на стороне джанго

print request.FILES :

<MultiValueDict: {u'file': [
<TemporaryUploadedFile: captcha_bg.jpg (image/jpeg)>,
<TemporaryUploadedFile: 001_using_git_with_django.mov (video/quicktime)>,
<TemporaryUploadedFile: ejabberd-ust.odt (application/vnd.oasis.opendocument.text)>
]}>

поэтому все три файла находятся под одним объектом request.FILES ['file']. как мне обрабатывать каждый файл, загруженный отсюда?


person Abu Aqil    schedule 12.05.2009    source источник
comment
Та же проблема и решение для одного элемента с несколькими: <input type="file" name="file" multiple />   -  person Mark    schedule 02.12.2012


Ответы (4)


for f in request.FILES.getlist('file'):
    # do something with the file f...

РЕДАКТИРОВАТЬ: Я знаю, что это был старый ответ, но я столкнулся с ним только сейчас и отредактировал ответ, чтобы он действительно был правильным. Ранее предполагалось, что вы можете выполнять итерацию непосредственно по request.FILES['file']. Чтобы получить доступ ко всем элементам в MultiValueDict, вы используете .getlist('file'). Использование только ['file'] вернет только последнее значение данных, найденное для этого ключа.

person Justin Voss    schedule 13.05.2009
comment
Есть идеи, почему request.FILES['file'] не работает? Мне любопытно. - person Mark; 02.12.2012
comment
@Mark, если вы имеете в виду, что файл не был загружен, он вернет пустую строку или список, но если вы имеете в виду, что вы загружаете, но все равно не можете получить файл из request.FILES['file']s, скорее всего, вам не хватает необходимых полей в input в вашем html-коде. По моему опыту, вам нужно использовать name="myfile" в input field, чтобы сделать его конкретным. В этом случае вы должны использовать request.FILES['myfile']. Использование file в качестве имени в html-коде затрудняет различение того, что есть что. - person Ibo; 28.09.2017
comment
Еще одна важная вещь при работе с несколькими файлами - это включение нескольких / form-data в ваш html-тег form, чтобы ваш тег формы, заключающий ваш тег input, был бы <form method="POST" enctype="multipart/form-data"> - person Ibo; 29.09.2017
comment
Десять лет спустя, и этот ответ все еще работает, спасибо! - person Mike Gostomski; 23.04.2020

Учитывая, что ваш URL-адрес указывает на envia, вы можете управлять несколькими файлами следующим образом:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from django.http import HttpResponseRedirect

def envia(request):
    for f in request.FILES.getlist('file'):
        handle_uploaded_file(f)
    return HttpResponseRedirect('/bulk/')

def handle_uploaded_file(f):
    destination = open('/tmp/upload/%s'%f.name, 'wb+')
    for chunk in f.chunks():
        destination.write(chunk)
    destination.close()
person Community    schedule 16.10.2009
comment
Вы не должны использовать имя файла, предоставленное пользователем, для записи на диск, его можно изменить для записи где угодно. Используйте случайное имя файла и сохраните исходное имя файла в базе данных только для презентационных целей. - person Riccardo Galli; 25.09.2013

Я не думаю, что все три файла будут находиться под одним объектом request.FILES['file']. request.FILES['file'], скорее всего, будет иметь либо 1-й файл, либо последний файл из этого списка.

Вам нужно однозначно назвать элементы ввода следующим образом:

<input type=file name="file1">
<input type=file name="file2">
<input type=file name="file3">

..Например.

РЕДАКТИРОВАТЬ: ответ Джастина лучше!

person Matt Kocaj    schedule 12.05.2009
comment
Django автоматически обрабатывает случай, когда несколько входов имеют одно и то же имя: он передает вашему коду список значений вместо одного значения. Вы можете увидеть список в опубликованном коде. - person Justin Voss; 13.05.2009
comment
Значит, этот 'MultiValueDict' является результатом, возможно, оболочки для объекта request.FILES ['file']? - person Matt Kocaj; 13.05.2009
comment
Да, request.FILES - это объект MultiValueDict, а request.GET и request.POST - объекты QueryDict, которые похожи. - person Justin Voss; 13.05.2009

Этот код является примером

    for f in request.FILES.getlist('myfile[]'):
        if request.method == 'POST' and f:
            myfile = f
            filesystem = FileSystemStorage()
            filename = filesystem.save(myfile.name, myfile)
person Ali Noori    schedule 29.05.2020
comment
этот ответ не имеет смысла. myfile [] - строка. Запись [] не приведет к включению его в список - person Rafael Santos; 09.12.2020