【Django】静的ファイル関連の設定について(画像,動画)

###Djangoにて画像ファイルなどの設定方法をまとめてみた

##静的ファイルとは
- cssファイル
- jsファイル
- 画像ファイル
- 動画ファイル

などのクライアントからのリクエストによって、内容が変化しないファイルのことを静的ファイルと言います。今回はその中で画像ファイルや動画ファイルなどの**ユーザからのアップロードを受ける**静的ファイルの設定についてまとめます。
cssファイルやjsファイルやユーザからのアップロードを必要としない画像等の場合についてはこちらをご参照ください。
https://qiita.com/Suchmos7/items/eb61727a3f65883028a6


## Setting.pyでの設定
設定が必要なパラメータは主に3つです。
- MEDIA_URL
- MEDIA_ROOT


**MEDIA_URL**
静的ファイル（img,video）配信用のURLを指定する。
settings.pyにて以下のように設定すると
http(s)://ホスト名/media/画像ファイル名
でアクセスできるようになる。

```python:settings.py
MEDIA_URL = '/media/'
```





**MEDIA_ROOT**
画像の保存先
あらかじめmanage.pyと同じ階層にmediaフォルダを作ってください。

cssファイルやjsファイルの場合、STATIC_ROOTという変数には本番用のファイルの保存先を記述し、開発環境ではSTATICFILES_DIRSという変数を使い、本番のときSTATIC_ROOTに切り替える、としていましたが、画像、動画の場合はありません。
なのではじめからMEDIA_ROOTを使用していきます。

```python:settings.py
MEDIA_ROOT = os.path.join(BASE_DIR,'media') 
```

ちなみにBASE_DIRはプロジェクト直下を指すパスで、以下のように同じくsettings.pyにて定義した変数。

```python:settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
```

##urls.pyでの設定
```python:urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app1.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```
まず、settingsとstaticをインポートします。
そしてurlpatterns変数に上記のように付け足します。
第一引数には静的ファイルの配信URL、document_root引数には静的ファイルの保存先を指定します。
これによりURLと保存先が紐づけられ、URLにアクセスしたとき、静的ファイルの保存先につながるようになります。

## htmlテンプレート内での呼び出し方
画像（動画）ファイルは以下の2種類に分けられます。

- データベースと相関性のない画像データの場合（HPの背景画像など）
この場合は、まずユーザからのアップロードを受けないファイル群になるでしょう。ですので、そもそもMEDIA_ROOTとして扱うものではないです。このタイプはcssファイルやjsファイルと同じ扱いになります。ですので以下URLにテンプレート内での呼び出し方を参考にしてください。

[静的ファイルの設定について（css,js）](https://qiita.com/Suchmos7/items/eb61727a3f65883028a6)

- データベースと相関性のある画像データの場合（ユーザごとのプロフィール画像など）
ユーザからアップロードを受ける画像は基本的にモデルに画像を登録してユーザごとにデータを分けたりすると思います。そして本記事では解説はしませんがDjangoのModelクラスにはImageFieldやFileFieldなどがあり、そこのフィールドにアップロードされた画像のURLを保存していきます。以下にmodelの例を書きます。

```python:models.py
from django.db import models

class Book(models.Model):
        title = models.CharField(max_length=100)
        image = models.ImageField(upload_to="/image/book/")

        class Meta:
               db_table = 'Book'

```
ImageFieldでは引数にupload_toを設定します。これはMEDIA_ROOT以下のpathを記述します。この場合画像保存先は下のようになっているイメージです。

```
--manage.py
 Lconfig
 Lmedia--image--book--指定先
               Latuhor
        Lvideo

```

さてこのImageFieldおよびFileFieldのテンプレートでの呼び出し方は
1. htmlレンダリングの際にモデルインスタンスを渡す
2. モデルインスタンス.フィールド名.urlでurlを取り出す
です。

```python:views.py
from django.shortcuts import render,redirect

from ./models import Book


def imageshowfunc(request):
      book = Book.obejects.get(title='面白い本') #Bookモデルからタイトルが面白い本を検索し取得
      return render(request, 'imageshow.html', {'book':book}) #辞書型引数でbookインスタンスを渡す

```

```html:imageshow.html
{%if book.image %}
<img src="{{ book.image.url }}"><!--インスタンス.フィールド名.url-->
{% endif %} <!-- このif文がないともし画像ファイルがない、場合エラーを吐き出してしまう-->

```



## settings.pyの簡単な仕組み説明
settings.pyにてMEDIA_ROOTを書いてmigrateした時点で、djangoは自動的に画像の保存先をMEDIA_ROOTに設定します。なので、urls.pyのurlパターンに何も書き加えなくても画像のアップロードは可能でその画像はMEDIA_ROOTで指定したPathに保存されます。**MEDIA_ROOTは画像の保存先を指定しています。**

しかし、その画像を呼び出したいときurlパターンに設定がないとdjangoはどこを参照すればよいのか分からなくエラーが出ます。つまり、**urlパターンは画像の参照先、配信URLをdjangoに対して指定しているのです。**