Django загрузка нескольких файлов при помощи HTML5

  • Python
Python: Django multiuploader logoМногие люди испытывают сложности с созданием форм для загрузки множества файлов, без Flash. В своих проектах мы используем Django и мы решили сделать полезный инструмент, который возьмет заботу о создании таких форм в Django на себя. В итоге получилось законченное приложение для Django, которое можно просто установить, и подключив его наслаждаться результатом. Приложение называется django-mutiuploader и его целью является максимально упростить загрузку множества файлов в приложениях Django.


Принцип работы
Приложение добавляет свою форму для загрузки файлов, после того как пользователь загрузит файлы и нажмет кнопку отправить (например отправить сообщение), в поле MultiuploaderField Вашей формы сообщения, передадутся id всех файлов, которые были загружены. Дальше Вы можете поместить все эти файлы в свою модель, в свой собственный storage (будь это AWS, собственный CDN или просто отдельная папка на сервере).

Установка и настройка приложения
Чтобы установить django-multiuploader, нужно запустить следующую команду (предполагается что pip уже установлен):
$ pip install django-multiuploader

Затем Вам нужно добавить 'multiuploader' в ваш INSTALLED_APPS и запустить
python manage.py syncdb

или если Вы используете South, запустить
python manage.py migrate multiuploader

Также, если Вы хотите чтобы отображались превью изображений при загрузке, Вам нужно выполнить sybcdb для sorl.thumbnail.

Для корректной работы, Вам понадобится django версии, как минимум 1.3.1 или выше.

Тажке стоит добавить 'multiuploader.context_processors.booleans' в Ваши TEMPLATE_CONTEXT_PROCESSORS.

Настройка
В settings.py Вы можете использовать следующие опции для конфигурации:
  • ALLOWED_FILE_TYPES — список расширений файлов, доступных для загрузки (например ['txt','zip','jpg','jpeg','flv','png']);
  • CONTENT_TYPES — список типов содержимого, доступных для загрузки (например ['image/jpeg', 'video/mp4','application/msword']);
  • MAX_UPLOAD_SIZE — максимальный размер для загрузки (в байтах)
  • MAX_FILE_NUMBER — максимальное количество файлов для загрузки (за один раз)
  • MULTI_FILES_FOLDER — путь к папке, в которой хранить файлы
  • FILE_EXPIRATION_TIME — время, после которого файлы могут быть удалены командой clean_files.

Все вышеперечисленные параметры, не обязательны.

Использование
Чтобы добавить возможность загрузки множества файлов, Вам нужно выполнить несколько шагов:

Добавить urlpattern (r'^your_uploads/', include('multiuploader.urls')) в Ваш urlpatterns.

Создать экземпляр формы MultiuploadForm в Ваших views и передать его в контекст.

Например:
from django.shortcuts import render_to_response
        from multiuploader.forms import MultiUploadForm
        
        def my_view(request):
            context = {
                'uploadForm':MultiUploadForm()
            }
            return render_to_response(your_template, context=context)

Далее нужно добавить в вашу форму, при помощи которой Вы хотите загружать файлы поле MultiuploaderField:
# Ваш forms.py
        
        from multiuploader.forms import MultiuploaderField
        class PostMessageForm(forms.Form):
            text = forms.CharField(label=u'Вопрос', widget=forms.Textarea)
            uploadedFiles = MultiuploaderField(required=False)
<code>
Затем Вам нужно отрендарить это поле в Вашем шаблоне:
<code>    
        <form method="POST" action="" enctype="multipart/form-data">
	    {% csrf_token %}
	    <p>
		    {{ form.text }}
		    {{ form.text.errors }}
		    {{ form.uploadedFiles }}
	    </p>
	    <p>
		    {% multiuploader_noscript form.uploadedFiles.html_name %}
		
		    <input id="send" type="submit" value="Send" class="button">
		    <a id="showUpload" type="button" class="button"><i class="attachment"></i>Attach files</a> 
	    </p>
        </form>
    
    {% multiuploader_form uploadForm form.uploadedFiles.html_name "$" "fileUploads" %}

В этом примере {% multiuploader_noscript form.uploadedFiles.html_name %} — template tag, который загружается в случае если в браузере выключен javascript.

Аргументы:
  • form.uploadedFiles.html_name — аргумент в темплейт тег, который указывает имя поля, в которое мы загружаем файлы.
{% multiuploader_form uploadForm form.uploadedFiles.html_name «fileUploads» %} template tag, который загружает код и всю необходимую логику для загрузки файлов.

Аргументы:
  • uploadForm — наша форма MultiUploadForm, которую мы передали в контекст
  • form.uploadedFiles.html_name — имя поля нашего MultiuploaderField
  • "$" — префикс jQuery (полезно при использовании в админ панели). Это необязательный параметр
  • «fileUploads» — id контейнера, в который будет помещена форма мултиаплоадера. Полезно для стилизации (например если мы хотим скрыть форму мультиаплоадера по умолчанию).

Шаблоны и кастомизация
  • multiuploader/widget.html — шаблон виджета MultiuploaderField здесь Вы можете изменить внешний вид и поведение виджета под свои нужды
  • multiuploader/form.html — шаблон форсы MultiUploadForm
  • multiuploader/noscript.html`` — шаблон, который используется в случае noscript.

Разработка и поддержка

Разработка идет в репозитории на BitBucket

Свои запросы на функционал, идеи, баг-репорты и прочее оставляйте в нашем баг-треккере

Благодарность
  • Sebastian Tschan за jQuery HTML5 Uploader (https://blueimp.net/).
  • Iurii Garmash за основу django multiuploader, на базе которой был разработан django-multiuploader.

Тестовое приложение
Тестовое приложение в стадии разработки, если возникли вопросы или сложности, пишите либо сюда либо в баг-треккер. Как только тестовое приложение будет готово, обновлю пост.

Лицензия
Проект опубликован под лицензией MIT.


5 комментариев

IvanKhamlenko
Добрый день. Скажите, пожалуйста, а можно ли использую Ваше приложение, сделать мультизагрузку файлов, и привязать их к одной модели? Например, у нас есть фотоальбом, и в фотоальбом сразу загрузить несколько фотографий.
Satchitananda
Да, вполне. Нужно просто сделать модель, которая унаследуется от BaseAttachment. Эта модель должна иметь поле ForeignKey на Вашу модель альбома.
IvanKhamlenko
Cпасибо за быстрый ответ. Извините, за свою малограмотность, но я только постигаю первые шаги в Django, и не совсем правильно понимаю что именно нужно сделать. Смотрите, например, есть статья, и в ней надо реализовать фотогалерею. Статья наполняется из админки. Правильно я делаю реализацию моделей?

class Article(models.Model):
    name = models.CharField(max_length=255)

class Img(BaseAttachment):
    img = models.ImageField(upload_to='uploads/')
    key = models.ForeignKey(Article)
Satchitananda
Если Article это фото альбом, то да, но есть еще пункты, которые нужно выполнить по инструкции, для установки Multiuploader
IvanKhamlenko
Спасибо. А BaseAttachment импортируется from multiuploader import BaseAttachment?

Оставить комментарий