Djangoでファイルアップロード機能を実装する方法を解説する

スポンサーリンク

この記事では、Django サーバにファイルをアップロードするための正確な手順について説明します。

ほとんどの Web アプリケーションや Web サイトでは、ユーザが自分のプロフ ィール写真や、ローカルコンピュータからサーバにファイルをアップロードすることができ ます。

私たちのチュートリアルでも同じことを再現します。

Django と ModelForms を使って、ファイルや画像を Web サーバにアップロードして処理する方法について見ていきましょう。

スポンサーリンク

Django にファイルをアップロードする

Django でファイルのアップロードを可能にするために必要なものに、さっそく取り掛かりましょう。

1. 前提知識

前回の Django Forms の記事で、フォームのデータを取得するために、Form オブジェクトの中で request.POST を使うことを見てきました。

form = ReviewForm(request.POST,request.FILES)

しかし、Django にファイルをアップロードするには、別の属性 request.FILES も含める必要があります。

なぜなら、アップロードされたファイルは request.POST の代わりに request.FILES という属性に保存されるからです。

コードはこんな感じになります。

enctype ="multipart/form-data"

Django には、異なるファイルタイプを扱うために、ImageField と FileField という別々のモデルフィールドがあります。

画像ファイル(.jpg/.jpeg/.png など)のみをアップロードする場合は ImageField を使います。

ファイルのアップロードを許可するには、

属性に以下の属性を追加する必要があります。

<form type = 'post' enctype = "multipart/form-data">

最後に、フォームの HTML タグは以下のようになります。

MEDIA_URL = /media/
MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’)

2. アップロードされたファイルを保存するために settings.py を修正します。

settings.pyの末尾に以下の行を追加します。

class EBooksModel(models.Model):
 
    title = models.CharField(max_length = 80)
    pdf = models.FileField(upload_to='pdfs/')
 
    class Meta:
        ordering = ['title']
     
    def __str__(self):
        return f"{self.title}"

ここです。

  • MEDIA_URL: URLのエンドポイントを指定します。これは、ユーザーがブラウザからファイルをアップロードするために行くことができるURLです。
  • MEDIA_ROOT: ルート。これは Django Templates の記事で、Templates の DIR 設定の下で以前に見たことがあります。

もし今理解できなくても、この記事の後半で理解できるようになります!

2 行目は、アップロードされたすべてのファイルを BASE_DIR (プロジェクトディレクトリ) に作成された ‘media’ というフォルダに格納するよう Django に指示しています。

このフォルダは手動で作成する必要があるので、アップロードされたファイルは全て以下の下線部の media フォルダに格納されます。

class UploadBookForm(forms.ModelForm):
    class Meta:
        model = EBooksModel
        fields = ('title', 'pdf',)

3. Django プロジェクトで Media フォルダを作成します。

さて、プロジェクトフォルダ内に、「media」という名前で新しいフォルダを作成します。

form = UploadBookForm(request.POST,request.FILES)

フォルダを作成したら、eBookアップロードのウェブページの作成に移ります。

E-Book アップロードウェブページの作成

ここで、顧客が持っている本のpdfファイルをアップロードするためのウェブページを作成してみましょう。

1. models.py で E-Book モデルを作成する

models.py で、新しい Django モデル “EBooksModel” を作成し、以下のコードを追加します。

def BookUploadView(request):
    if request.method == 'POST':
        form = UploadBookForm(request.POST,request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponse('The file is saved')
    else:
        form = UploadBookForm()
        context = {
            'form':form,
        }
    return render(request, 'books_website/UploadBook.html', context)

ここで

  • よく知られたモデルである CharField を使い、クライアントが送信した PDF の名前を格納します。
  • FileField は、クライアントがアップロードするファイルに対して使用されます。
  • Upload_toオプションは、ファイルがメディア内に保存されるパスを指定します。例えば、’pdfs/’を使用していますが、これはメディア内のpdfsというフォルダにファイルが格納されることを意味します。
  • クラス Meta と def_str_to_to_: Django models の記事で学びました。

注意: アップロードされたファイルはデータベースには保存されません。

ファイルのインスタンスだけがそこに保存されます。

したがって、そのインスタンスを削除しても、アップロードされたファイルは media フォルダの中に残ります。

ファイルのインスタンスというのがどういう意味かは、この記事の後半でわかると思いますので、お待ちください!

2. forms.py で UploadBookForm を作成する

EBooksModel を forms.py にインポートし、新しい ModelForm “UploadBookForm” を作成します。

Django Forms で学習した知識を使って Form を作成します。

<form method ='post' enctype ="multipart/form-data">
    {% csrf_token %}
    {{form}}
    <input type="submit" value = "Submit">
</form>

3. views.py で BookUploadView を作成します。

ここでのコードは Django Forms で書いたものと同じになります。

しかし、ここではアップロードされたファイル(request.POSTの代わりにrequest.FILESに置かれます。

)を収容する必要があります。

そのためには、以下のように request.POST と一緒に request.FILES を追加するだけです。

path('book/upload', BookUploadView, name ='BookUploadView')

したがって、完全なコードは次のようになります。

python manage.py makemigrations
python manage.py migrate

4. UploadBook.html テンプレートの作成

次に、テンプレートファイルに

属性を作成する必要があります。

そこで、テンプレートファイル「UploadBook.html」を作成し、以下を追加します。

admin.site.register(EBooksModel)

enctype =”multipart/form-data” を追加しないと、フォームが動作しません。

最後に、ViewにURL(book/upload)を対応させましょう。

5. UploadBookViewのURLパスの作成

urls.py で、Django の URL マッピングで見た方法で、UploadBookView をリンクするためのパスを ‘book/upload.’ に追加します。

from django.conf import settings
from django.conf.urls.static import static
 
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

新しいモデルを作成したので、もう一度マイグレーションを実行する必要があります。

そこで python シェルで以下のコマンドを一つずつ入力します。

Request POST
Request POST

それでは、サーバを起動して、ブラウザを確認してみましょう。

Django Project Directory
Django Project Directory

ほら、アップロードフォームができました。

pdfを選択して、送信ボタンをクリックします。

Media
Media

送信ボタンを押すと、「ファイルが保存されました」というページが表示されます。

Browser
Browser

mediaフォルダに移動すると、pdfフォルダがあり、その中に投稿したpdfがあります。

Browser
Browser

新しく作ったモデルを、管理サイトで登録します。

Browser
Browser

次に、ブラウザで管理サイトを読み込んで、EBooksModelに移動し、先ほど登録した要素を選択します。

Media/pdfs
Media/pdfs

ここで、pdfフィールドに注目してください。

Currently: というオプションが表示されます。

その前に書かれているpdfs/cprogramming_tutorial.pdfというパスは、インスタンスと呼ばれています。

したがって、pdfs/ ファイルのインスタンスです。

Django はファイルのインスタンスだけを保存し、ファイルそのものは保存しません。

従って、管理サイトからモデルを削除しても、pdf ファイルは media フォルダに残っています。

アップロードされたファイルをブラウザのフロントエンドから見る

上記のWebページでは、インスタンスがリンクとして表示されています。

しかし、それをクリックすると、エラーメッセージが表示されます。

これは、エンドポイントがマッピングされていないために起こります。

Admin Site
Admin Site

さて、このエラーを修正するには、このエンドポイントを特定のファイルにマップする必要があります。

これを行うには、urls.pyに移動して、次のコードを追加します。

Error Message
Error Message
Urls
Urls

この行を読めば、私たちが何をしているのか、おおよその見当がつくと思います。

ここです。

  • settings.py で debug = True としているので、settings.DEBUG は常に True になります。
  • サイドのif関数で、上記のurlpatternsに static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) を追加するコードです。
Debug 1
Debug 1

static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) という行は、このように考えることができる。

ホストサイト(http://127.0.0.1:8000/)に、エンドポイントを追加しているところです。

  • MEDIA_URL(冒頭では「/media/」としています)
Media Settings
Media Settings
  • そして、document_root(mediaフォルダ内のpdfファイルの場所)です。

つまり、先ほどアップロードしたcprogramming_tutorial.pdfを見るには、http://127.0.0.1:8000/media/pdfs/cprogramming_tutorial.pdfにアクセスします(MEDIA_URL(‘/media/’)が使われていることを確認してください)。

これはurls.pyの上記のコードが行うことです。

これで、サーバをリロードして、Django の管理ページで先ほどのインスタンスをクリックしても、エラーは発生しなくなりました。

Admin Site
Admin Site

インスタンスのリンクをクリックしてみてください。

Pdf Browser
Pdf Browser

これで、ブラウザ経由で pdf を見ることができるようになりました!

まとめ

以上です! Django にファイルをアップロードするために必要なことをすべて学んでいただけたでしょうか。

また、このトピックについては、公式ドキュメントからさらに学ぶことができます。

練習問題: これまでの記事で得た知識を使って、あるウェブページで利用可能なすべての電子書籍とそれを閲覧するためのリンクを表示するウェブページを作ってみてください。

Django のトピックに関するより高度なチュートリアルにご期待ください!

タイトルとURLをコピーしました