python

djangoでDBに画像を保存して表示するまでする方法

テキストを保存するように、テーブルとカラムをmodel.pyに書き込んで、migrateするだけでは画像を書き込むのは上手くいかないので、実装を踏まえて説明していきます。

画像データをどのように扱うにせよ、DBは必要になってきますので、model.pyに必要なカラムを書いていきます。

models.py

from django.db import models

class SnsModel(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()
  author = models.CharField(max_length=100)
  # 画像をアップロード時にはpillowライブラリが使われるので、pipでインストールする必要あり
  # 前提としてブランクの時にはデフォルトでどこに保存するかの設定をsettings.pyに書き込む必要あり
  images = models.ImageField(upload_to='') # upload_toはどこのディレクトリに画像をアップロードするかの設定
  good = models.IntegerField()
  read = models.IntegerField()
  readtext = models.CharField(max_length=200)

この状態で、migrateしていきたいのですが、ここでエラーが出る人と出ない人が出てくると思います。
それは、Pillowモジュールがインストールされているかどうかです。
djangoでは画像を扱う際にPillowモジュールを使用します。
そこで、pip install Pillow をした後にmigrateしてください。

python manage.py makemigrations
python manage.py migrate

ついでに、管理画面でデータの入力と確認をしていきたいので、admin.pyを変更して表示させるようにします。

from django.contrib import admin
from .models import SnsModel

# Register your models here.
admin.site.register(SnsModel)

これで、Sns modelsというテーブルが確認できます。
この状態では一応入力できますが、画像が保存されません。

そこで、models.pyのコメントに書かれている通りに、settings.pyに画像の保存先を書いてあげます。最下部に下記のように追記してあげます。

settings.py

# ... ここまでに他の設定が書かれている ...

STATIC_URL = '/static/'

# ... 追記部分 ...

# 画像を保存する先の指定
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# 画像をdjango側で読み込むための設定
MEDIA_URL = '/media/'

ここまで、できたら管理画面にアクセスして、データ入力してみてください。
そうすると選択した画像がmediaディレクトリに反映されていることが分かります。

実はまだこれで完成ではありません。入力したデータを確認して、画像のリンクをクリックして挙動をチェックしてみてください。
おそらく、エラーになると思います。

これは、画像をdjango側で取り扱うための設定をsettings.pyに書きましたが、urls.pyに対応する画像のpathを書いていないためです。

ただ、一つ一つの画像のパスを書いていくという無駄な作業はしたくありません。
そこで、djangoは簡単に画像を紐づけてくれる機能を提供してくれています。

画像関係のファイルを扱うための設定が詳しく載っています。
https://docs.djangoproject.com/en/3.0/howto/static-files/#serving-files-uploaded-by-a-user-during-development

使い方は簡単で、urls.pyに下記のように書くだけです。

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('snsapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.pyで設定したMEDIA_URLとMEDIA_ROOTをimportして、繋ぎ込みをしてあげるだけです。

これで無事に画像の保存から表示までできるようになりました。