PythonMania

普段はロボットとAIを組み合わせて色々作ってます。Python関係以外も色々投稿していくと思います。

【Django】フォームを使ってフォルダごとファイルをアップロードしてみる

f:id:mizuhiki0111:20190430175940p:plain




通常は単一のファイルをアップロードする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ディレクトリに保存されていると思います。