通常は単一のファイルをアップロードするImageFieldやFileFieldですが、今回はこれらのフォームを使ってフォルダの中身を一括してアップロードしてみたいと思います。
※今回の実装は「HTMLInputElement.webkitDirectory」という機能を使用して作られています。
以下のサイトに記載の通り、webkitDirectoryは標準機能ではないため環境によってはうまく動作しない場合があります。
なので本番環境等での使用はオススメしません。。
developer.mozilla.org
①models.py
models.pyは単一ファイルのアップロード機能を作る場合と変わりません。
from django.db import models class FolderUpload(models.Model): file = models.ImageField('画像ファイル') def __str__(self): return self.file.url
②forms.py
from django import forms class FileFieldForm(forms.Form): file_field = forms.ImageField(widget=forms.ClearableFileInput(attrs= {'multiple': True, 'webkitdirectory': True, 'directory': True}))
フォームの作成ではwidgetを使用し、「webkitdirectory': True, 'directory': True」を指定しています。
③views.py
views.pyです。FormViewを使用してクラスを定義しています。
class FolderUploadView(FormView): form_class = FolderUploadForm template_name = 'myapp/upload.html' success_url = 'myapp/result.html' def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) files = request.FILES.getlist('file_field') if form.is_valid(): for file in files: new_file = FolderUpload(file=file) new_file.save() return self.form_valid(form) else: return self.form_invalid(form)
④urls.py
from django.conf.urls import url from . import views urlpatterns = [ url('upload/', views.FolderUploadView.as_view(), name='upload'), ]
⑤upload.html
<table> <form action="{% url 'upload' %}" method="POST" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <input type="submit" id="upload_files" name="upload_files" value="submit" webkitdirectory directory /> </form> </table>
inputタグのところで「webkitdirectory directory /」と記載しておきます。
フォルダをアップロードすると、フォルダ内のファイルが一括してmediaディレクトリに保存されていると思います。