こんにちは。のっくんです。
今日の記事では、Djangoのファイルアップロード機能を実装する方法を紹介します。
「Djangoでファイルアップロードページを作りたい」
そんな方に読んでいただければと思います。
[toc]
完成形
作成するページの見た目は以下のようなシンプルなものです。

Descriptionにアップロードするファイル名、Documentにアップするファイルを指定します。
Uploadボタンを押すと、アップロードされます。
アプリケーションの作成
以下のコマンドでmosaic_appと言う名前のプロジェクトを作成して、その中にhelloと言う名前のアプリケーションを作成します。
django-admin startproject mosaic_app cd mosaic_app/ python manage.py startapp hello
このhelloアプリケーションにファイルのアップロード機能を実装します。
├── mosaic_app │ ├── db.sqlite3 │ ├── hello │ ├── manage.py │ ├── media │ ├── mosaic_app │ └── static
画像のアップロード先はmedia/documentsディレクトリにしたいと思います。
プロジェクト全体の設定とURL
画像をアップロードするディレクトリを指定します。
settings.pyの下の方に以下を追加しましょう。
mosaic_app/settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
また、タイムゾーンを日本にしておきます。
TIME_ZONE = 'Asia/Tokyo'
URLの設定は以下のようにしておきます。
mosaic_app/urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('hello/', include('hello.urls')) ]
hello/urls.py
urlpatterns = [ path('upload', views.model_form_upload, name='upload') ]
モデルの作成
では早速モデルを作っていきましょう。helloアプリの中にあるmodels.pyを以下のようにします。
hello/models.py
from django.db import models class Document(models.Model): description = models.CharField(max_length=255,blank=True) document = models.FileField(upload_to='documents/') uploaded_at = models.DateTimeField(auto_now_add=True)
documentがFileFiledで定義されています。ここでファイルのアップロード先を(documents/)にしています。この設定によってmedia/documentsに画像がアップロードされるようになります。
DateTimeFieldを定義して投稿日時が分かるようにしています。auto_now_addを指定することで自動的に投稿日時がデータベースに書き込まれるようになります。
フォームの作成
このファイルは存在しないので自分で新しく作成します。
hello/forms.py
from django import forms from .models import Document class DocumentForm(forms.ModelForm): class Meta: model = Document fields = ('description', 'document', )
fieldsのなかに投稿日時はありませんが、システムで自動的に追加されるようにしてあるのでユーザが指定する必要はありません。
ビューの編集
ビューでは以下の関数を作ります。
hello/views.py
from django.shortcuts import render,redirect from .forms import DocumentForm from .models import Document def model_form_upload(request): if request.method == 'POST': form = DocumentForm(request.POST, request.FILES) if form.is_valid(): form.save() return redirect('index') else: form = DocumentForm() return render(request, 'hello/model_form_upload.html', { 'form': form })
model_form_uploadでは、投稿されたファイルの保存やフォームの受け渡しを行なっています。投稿ページはmodel_form_upload.htmlにしています。
テンプレートの作成
以下のようにテンプレートを作成します。
hello/templates/hello/model_form_upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload</title> </head> <body> <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">Upload</button> </form> </body> </html>
enctypeを指定しないと上手くアップロードできないそうなので気をつけてください。
以上のコードを記載したら、以下のコマンドを実行してください。
python manage.py makemigrations hello python manage.py migrate python manage.py runserver
ブラウザで”localhost:8000/hello/upload”にアクセスするとページが表示されます。
アップされたファイルを確認する方法
*2019/1/7 追記
これは必須ではありませんが、以下のようにするとアップされたファイル名や日時を確認できます。
hello/views.py
from django.shortcuts import render,redirect from .forms import DocumentForm from .models import Document def model_form_upload(request): if request.method == 'POST': form = DocumentForm(request.POST, request.FILES) if form.is_valid(): form.save() return redirect('index') else: form = DocumentForm() obj = Document.objects.all() return render(request, 'hello/model_form_upload.html', { 'form': form, 'obj': obj })
hello/templates/hello/model_form_upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload</title> </head> <body> <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">Upload</button> </form> {% for item in obj %} <tr> <td>{{ item.description }}</td> <td>{{ item.document }}</td> <td>{{ item.uploaded_at }}</td> <tr> {% endfor %} </body> </html>
参考URL
How to Upload Files With Django:
https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html
以上です。お疲れ様でした。