Djangoで画像やファイルをアップロードする方法
Djangoはやはり便利ですね。色々良しなにやってくれるから俺は結構気に入ってます。もちろんファイルの扱いも良しなにしてくれます。
今回はファイルアップロード出来るようにする方法についてお話しします。
DjangoではFileField や ImageFieldと言うのが提供されていて、これらを利用すると非常に簡単にアップロードファイルを取り扱うことができます。
FileField や ImageFieldを利用すると、DB上にはアップロードされたPathが入り、実ファイルは指定したサーバー上に保存されます。パフォマンス上、決してDBにファイルが入ることはありません。
では、とりあえずやってみましょう。
「settings.py」にMEDIA_ROOTとMEDIA_URLを設定
import os
ROOT_PATH = os.path.dirname(__file__) + '/..'
...
MEDIA_ROOT = ROOT_PATH + '/media/'
...
MEDIA_URL = '/media/'
はファイルが保存されるサーバー上のPathを指定します。MEDIA_ROOT
になります。MEDIA_URL
はファイルの公開URLを指定します。上記の例だと
http://example.com/media/
FileField や ImageFieldを使いModelを設定
...
upload = models.FileField(upload_to='uploads/')
...
FileFieldには
属性を指定します。upload_to
この例だとproject_root/media/uploads/のところにファイルが保存され、DBにはuploads/filenameとそのPathが保存されます。
DB上に該当するColumnを作成しておくことをお忘れなく!
urls.pyを設定
アップロードされたファイルが見られるように公開します。
...
from django.conf import settings
from django.conf.urls.static import static
...
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...
これであなた自身のパソコンやテストサーバーでは正常にファイルが見れるはずです。
お疲れ様でした。
FAQ
上の通りにしても、テスト機では動くけど本番サーバーでは動かないよ?
上記の3ステップであなた自身のパソコンやテストサーバーでは正常にファイルが見れるはずです。
どういうことかと言うと、本番運用しているサーバーならApacheなどWebサーバーをかまして運用するのが普通だから、本番ではWebサーバーの設定も変えてあげないといけないと言うことです。
Apacheを例として取り上げると、下記のような設定を追加する必要があります。
...
Alias /media/ /project_root/media/
...
アップロードされたファイル名を変更して保存したい
会員のPKやIDなどを使ってファイル名付けて保存したい、もしくはセキュリティ問題などの理由でファイル名を変更して保存したい方結構いると思います。そんな方は下記のSnippetを使ってみてください。PKを利用して新たにファイル名を付けるものです。
def path_and_rename(path, prefix, suffix):
def wrapper(instance, filename):
ext = filename.split('.')[-1]
if instance.pk:
filename = '{}{}{}.{}'.format(prefix, instance.pk, suffix, ext)
else:
filename = '{}.{}'.format(uuid4().hex, ext)
return os.path.join(path, filename)
return wrapper
使い方の例はこちら。
upload = models.FileField(upload_to=path_and_rename('uploads/', 'member-', '-doc'))
この例だと
と言うファイル名で保存されます。uploads/member-1234-doc.ext
公式文書のURL教えて!
https://docs.djangoproject.com/ja/3.0/faq/usage/#how-do-i-use-image-and-file-fields
ディスカッション
コメント一覧
まだ、コメントがありません