0.0 主な内容
django(本記事ではversino3.1)でのファイルアップロードに関してまとめます。
この記事を読むことで、
1 テキストのアップロード
2 画像のアップロード
3 オーディオのアップロード
の方法について知ることができます。
主にdjangoやプログラミング初心者を対象とした記事ですが、djangoアーキテクチャの全体像について、基本的な内容は既知のものと想定しています。
また、本記事中では、
1 post_fileディレクトリ下で下記のコマンドにてプロジェクトを開始し、
$ django-admin startproject post_file .
2 その後template、static、mediaディレクトリを作成し、以下のようなディレクトリ構成になっている前提とします。
$ project/(プロジェクトディレクトリ)
.
│── config/(設定ディレクトリ)
│ │── __init__.py
│ │── settings.py
│ │── urls.py
│ │── wsgi.py
│── post_file_app/(アプリケーションディレクトリ)
│ │── __initi__.py
│ │── admin.py
│ │── apps.py
│ │── migrations
│ │ │── __init__.py
│ │── models.py
│ │── test.py
│ │── views.py
│── manage.py
│── template/
│── static/
│── media/
│ │──image/
│ │──audio/
1.0 ファイルアップロードまでの主な流れ
ファイルアップロードに関しては、
1 管理者画面から(サイト管理者が)アップロード
2 ユーザーフォームから(サイト利用者が)アップロード
の二つが考えられますので、以下、場合分けします。
1.1 管理者画面から(サイト管理者が)アップロード
1.1.1 settings.pyに設定を追記する。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'post_file_app',#これを追記
'media',#これを追記
]
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent#これを追記
MEDIA_ROOT = os.path.join(BASE_DIR,'media')#これを追記
MEDIA_URL = '/media/'#これを追記
djangoではアップロードした画像やオーディファイルを直接データベースには格納せずに、事前に用意したファイルに格納し、必要な時はそのパスからファイルを取得します。上記では、MEDIA_ROOTにてその格納するディレクトリを指定しています。
また、MEDIA_URLは、ファイルを表示するときに、/media/ と言うurlを割り当てて表示するという設定です。
1.1.2 model.pyにてアップロードするデータのレイアウトを定義する
class PostFile(models.Model):
usersname = models.CharField(max_length=50)#テキストアップロード
image =models.ImageField(upload_to='images/',verbose_name='image',null=True,blank=True)#画像アップロード
audio = models.FileField(default='', upload_to='audio/')#オーディオアップロード
def __str__(self):
return self.usersname
何をアップロードするかによって、CharField、ImageField、FileFieldを使い分ける点に注意します。
以下二つのコマンドでモデルのマイグレーションも忘れずに行います。
$ python manage.py makemigrations
$ python manage.py migrate
1.1.3 admin.pyに設定を追記し、管理者画面からアップロードできるようにする
model.pyでPostFileクラスを定義しただけでは、管理者画面からアップロードできません。
以下のようにadmin.pyに追記することで、管理者画面からアップロードができるようになります。
from .models import PostFile
admin.site.register(PostFile)
1.2 ユーザーフォームから(サイト利用者が)アップロード
この場合、単なる管理者画面上からのアップロードに加えて、新たに
1 入力フォームを作成(htmlファイル作成、form.py作成)
2 アップロードするファイルのvalidationの実装(views.pyにてロジックを記載)
が必要になります(ただし、本記事内ではvalidationを自作しないので、コードは少しし書く程度です)。
1.2.1 入力フォームの作成
まずはhtmlファイルを用意します。project/template/ディレクトリに、post.htmlファイルを作成しまし、下記のとおり書きます。
<!doctype html>
<html lang="en">
<head>
</head>
<body >
<form method="POST" action='' enctype='multipart/form-data'>{% csrf_token %}
{{ form.username }}
{{ form.image }}
{{ form.audio }}
</body>
</html>
ここでまず、encenctype='multipart/form-data'と言うのは画像やオーディオファイルをアップロードするときにhtmlのformタグ内に記載する必要があります。これを省くと、のちにdjangoは画像、オーディオファイルを取得できません。
また、{% csrf_token %}も呪文のようなもので、ファイルアップロード時に必須となります。
さらに、username、image、audioは、すでに書いたproject/post_file_app/model.pyで記載した変数名(username、image、audio)と一致させる必要があります。
では次にform.pyをpost_file_app内で新たに作成し、以下を追記し入力フォームを作成します。
from django import forms
from .models import PostFile
class PostFileForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['username'].widget.attrs.update({'placeholder':'text'})
self.fields['image'].widget.attrs.update({'placehodler':'image upload'})
self.fields['audio'].widget.attrs.update({'placehodler':'audio upload'})
class Meta:
model = TestPost
fields = ('text','image','audio')
最後に作成したフォームを表示するために、views.pyでビューを作成し、urls.pyでビューに対してurlを割り当てます。
from django.shortcuts import render,redirect
from django.views.generic import CreateView
from .forms import PostFileForm
class PostFileView(CreateView):
def post(self,request,*args,**kwargs):
form = PostFileForm(request.POST,request.FILES)
content_dict={
'form':form
}
if not form.is_valid():#ファイルが正しく入力されているかチェック(validation)
return render(request,'error.html')#error.htmlは、記事中では作成してませんが、各自用意してください。
form.save()
return redirect('success_page')
def get(self,request,*args,**kwargs):
form = PostFileForm(data=request.GET)
return render(request,'post.html',{'form':form,})
ここで、formと言う変数が出ていますが、これは既述したpost.htmlのform.username、form.image、form.audioのformと一致させてください。
また、PostFileForm( )の引数として、request.POSTとrequest.FILESとありますが、
前者はdjangoがテキストを、後者は画像やオーディオファイルを取得するために必要なものです。
from django.urls import path
from .views import Register,LoginView,LogoutView
from mystudio.views import RenderPostedSong
from .views import PostSongView,TestPostView,TestPostView,RenderTestPost
urlpatterns = [
path('post_file_view/',PostFileView.as_view(),name='post_file_view'),
path('success/',success,name='success_page',#本記事内ではviewを定義していません
path('error/',error,name='error_page',#本記事内ではviewを定義していません
]
終わり
以上です。これでdjangoにてテキスト、画像、オーディオファイルのアップロードができるようになりました。