django　画像をアップロードする画面を作る

#env
python3.6.8
win10

#はじめに
今回はdjangoで画像をアップロードする画面を制作します。以下手順でdjango上の画像をアップロードし表示する事ができます。それぞれの詳しい説明やトリッキーな設定方法などは他者に任せて、この記事ではなるべく記事をご覧頂いていたみなさんに__早く　正確に　簡単に__　django上で画像をアップロードして頂く事に主眼を置きました。そのためweb閲覧ユーザの殆どから求められていないわかりずらい説明は一切省いてます。進めていくうちに言葉足らずな箇所など出てくるかと思いますが乱筆故予めご了承頂ければ幸いです。それではいきましょう。

#いまからつくる画面
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/5afcd9bf-d2ba-e311-ad2f-3b8f0cecb6da.png)

写真をアップロードする画面をつくります。上記イメージのように実際にアップロードしたら表示させてみましょう。


#agenda

以下ステップで画像をアップデートする画面を構築する事が出来ます。項目が多く慣れるまで時間がかかりますが慣れてしまえば5分前後で画面を作る事が出来ます。

ライブラリインストール
メディア用ディレクトリの追加
URLの設定
モデル　　👈👈👈👈👈　設定済の場合はこのセクションから
フォーム
ビュー
テンプレート
マイグレーション
管理ツール
参考

# ライブラリインストール

django上で画像を扱うにはpillowというライブラリが必要ですので下記のコマンドでインストールしてください。

```
pip install pillow
```

# settings.pyメディア用ディレクトリの追加

画像の保存先を指定する為にsettings.pyに以下のように追加・修正します。

```
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
```

指定したのですから実際にフォルダも作成しましょう。プロジェクトフォルダの直下に「media」という名前のフォルダを作成します。もしわからなければmanage.pyを探してください。そこと__同じディレクトリ階層__にmediaというフォルダを作成してください。ここに画像がアップロードされます。

# URLの設定　プロジェクトのurls.py

urls.pyはアプリケーションとプロジェクトと２つある場合がありますね。今回はプロジェクトのurls.pyの末尾に以下の設定を追加します。


#プロジェクトのurls.py
```
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

敢えて難しい言い方で説明するとディスパッチャの設定(urls.py)にメディアファイル公開用のURLを追加します。

#アプリケーションのurls.py

```
    path('model_form_upload/', views.model_form_upload, name='model_form_upload'),
```

当たり前ですがプロジェクトとアプリケーションを間違えると動かないのでよく確認してください。

#モデル

さて、まず画像を扱うためのモデルを書きましょう。様々な書き方がありますが私はdb設計をしたらまずモデルを書きます。
 
```
from django.db import models

class Document(models.Model):
    description = models.CharField(max_length=255, blank=True)
    photo = models.ImageField(upload_to='documents/', default='defo')👈👈👈👈👈
    uploaded_at = models.DateTimeField(auto_now_add=True)
```

upload_toを’documents’にしておくことで、/media/documentsに画像が保存されます。mediaは、そう先程あなたが作成したフォルダですね。そこの中に画像が格納されるようになったという事です。
 
#フォーム

```	
from django import forms
from .models import Document👈👈👈👈👈
 
 
class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('description', 'photo',)
```

from .models import Document　を書くのを忘れないようにしてください。👈👈👈👈👈

#ビュー
```
from django.shortcuts import render, redirect
from .forms import DocumentForm👈👈👈👈👈
from .models import Document👈👈👈👈👈
 
 
def index(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            #return redirect('apprication:model_form_upload')👈👈👈👈👈
            return redirect('apprication:index')👈👈👈👈👈


    else:
        form = DocumentForm()
        obj = Document.objects.all()
 
    return render(request, 'apprication/model_form_upload.html', {👈👈👈👈👈
        'form': form,
        'obj': obj
    })
```

from .forms import DocumentForm
from .models import Document
を書くのを忘れないようにしてください

また

```
return redirect('apprication:model_form_upload')
```

と記載がありますね。これは/model_form_uploadへ飛ばすという意味です。例えばページをトップページに遷移させたい時は以下のように設定します。※indexがtopなら

```
return redirect('apprication:index')
```

既存のままページ遷移させたくない時は以下のように設定してください。ページ遷移はせずにアップロードした文字や画像が表示されるはずです。またこのタイミングでmediaフォルダに画像がアップロードされます。

```
#return redirect('apprication:model_form_upload')
```

さてredirectの次はrenderです。

```
return render(request, 'apprication/model_form_upload.html', {
```

バリデーションチェックが通った時のどのhtmlへ向かうか指定します。model_form_upload　と　apprication/model_form_upload.html　はあなたの環境に合わせて変更してください。書き方が違う事に注意してください。

#テンプレート　\templates\apprication\model_form_upload.html

題名の箇所に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><img src="{{ item.photo.url }}" width="100" height="100"/></td>
        <td>{{ item.uploaded_at }}</td>
    <tr>
    {% endfor %}
    </body>
</html>
```

#マイグレーション

以下コマンドでdb構成を再定義します。

```
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
```

#実装の確認

まず以下URLをたたきましょう。

```
http://127.0.0.1:8000/model_form_upload/
```

画面が表示されたら適当に文章や画像を入力してボタンを押して

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/8a7e17ec-8044-2da1-db9f-1d36ede48b5f.png)


正常にあなたが作成したmediaフォルダの中に

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/8b233300-e147-7118-de6b-d56af5860b52.png)

画像がアップロードされていれば確認OKです。何回か実施してみましょう。のちに管理ツールで画像を削除する事も可能です。

![0123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/62dbf56f-7135-4fc3-ed32-1dcbb2762122.png)



#管理ツール

管理ツール上に項目を登録すれば画像を削除する事ができます。http://localhost:8000/admin　で管理者権限でログインします。今回は管理者ツールでデータを作成し、web上で実際に表示できるか確認をしてみましょう。

#admin.py

```
from django.contrib import admin
from .models import Document

# Register your models here.
admin.site.register(Document)
```

管理ツールでデータを追加する事も可能です。
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/14c0baf8-aad5-d31b-1b70-135be8ff4bd4.png)

実際のサイトにいくと・・・・

![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/5afcd9bf-d2ba-e311-ad2f-3b8f0cecb6da.png)

先程管理者ツールで入力したデータが格納されている事がわかりました。




#番外編

ユーザを作っていない場合には以下でユーザを作成しましょう。

```
python manage.py createsuperuser
```

ユーザ名(admin)
メールアドレス(admin@no.com)
パスワード(適当)