本に合わせた画像を表示させる

はじめに

前回の続きで、今回は本に合わせて画像を表示させることを行います。
urhayataro.hatenablog.com

やることはBookモデルで画像を扱えるようにしてモデルを作成します。その後、cssでサイトの見た目を整えます。


本の画像を表示させる

まずはBookモデルに画像を扱うためのフィールドを追加します。フィールドの追加はbook/models.pyに以下を追加しますが、その前にIntegerFieldを使用するために、以下でPillowをインストールします。

pip install pillow

できれば以下を追加します。

class Book(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    thumbnail = models.ImageField() # 追加
    category = models.CharField(
        max_length=100,
        choices = CATEGORY
        )
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)

    def __str__(self):
        return self.title

次に以下のコマンドを実行します。

python3 manage.py makemigrations

すると以下のメッセージが表示されます。
内容はthumbnailフィールドを追加する時に今まで作成したデータはどのような画像を使うかというものです。

ここでは2を選択して追加した場所を以下のように変更しましょう。

thumbnail = models.ImageField(null=True, blank=True)

nullはデータベースにデータが入っていないことを許容するか、blankはフォームに入力されたデータが空でも許容するかを表しています。

変更すれば、もう一度モデルの作成をしましょう。

python3 manage.py makemigrations
python3 manage.py migrate

画像ファイルを保存する場所の指定と画像の結びつけ

モデルで画像を扱う際、画像を保存する必要があります。まずbookproject/settings.pyに以下を追加します。

MEDIA_URL = '/media/'

MEDIA_ROOT = BASE_DIR / 'media'

また次のコマンドでbookやbookprojectと同じ階層にディレクトリを作成します。

mkdir media

この作成したmediaという場所に本の画像が保存されることになります。

ここからは画像とURLを結びつけます。bookproject/urls.pyに以下を追加します。

from django.conf import settings
from django.conf.urls.static import static

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

追加したsettings.MEDIA_URLはsettings.pyの中のMEDIA_URLを示しています。リクエストされたURLとMEDIA_URLで指定した文字列が同じ場合にsettings.MEDIA_ROOTを呼び出します。
settings.MEDIA_ROOTはsettings.pyで指定した画像が保存される場所を示しています。

ここまでできれば、サーバーを立ち上げ、127.0.0.1:8000/admin/にアクセスします。
以下のように画像の選択ができます。

合わせて画像が表示されるか確認してみると良いでしょう。


画像の表示ができれば、トップページじ画像を表示させましょう。
book/templates/book/index.htmlに以下を追加します。

{% for item in object_list %}
        <div class="p-4 m-4 bg-light border border-success rounded">
            <h2 class="text-success">{{ item.title }}</h2>
            <img src="{{ item.thumbnail.url }}" class="img-thumbnail" /> # 追加
            <h6>カテゴリー: {{ item.category }}</h6>
            <div class="mt-3">
                <a href="{% url 'detail-book' item.pk %}">詳細へ</a>
            </div>
        </div>
    {% endfor %}

トップページに画像が表示されていることを確認しましょう。

最後にfieldsにthumbnailを追加します。まずはbook/views.pyに以下を追加します。

class CreateBookView(LoginRequiredMixin, CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = {'title', 'text', 'category', 'thumbnail'} # 追加

class UpdateBookView(LoginRequiredMixin, UpdateView):
    template_name = 'book/book_update.html'
    model = Book
    fields = {'title', 'text', 'category', 'thumbnail'} # 追加

また、フォームで画像を扱うためにbook/templates/book/book_create.htmlを以下のように修正します。

{% extends 'base.html' %}

{% block title %}書籍作成{% endblock %}

{% block content %}
    <form method="POST" enctype="multipart/form-data" class="p-4 m-4
    bg-light border-success rounded form-group">{% csrf_token %}
        {{ form.as_p }}
        <input type='submit' value='作成する'>
    </form>
{% endblock content %}

合わせてbook/templates/book/book_update.htmlを以下のように修正します。

{% extends 'base.html' %}

{% block title %}書籍修正{% endblock %}

{% block content %}
    <form method="POST" enctype="multipart/form-data" class="p-4 m-4
    bg-light border-success rounded form-group">{% csrf_token %}
        {{ form.as_p }}
        <button type='submit'>修正する</button>
    </form>
{% endblock %}

cssの設定

cssを適用するために、bookproject/templates/base.htmlに以下を記述を追加します。

{% load static %} # 追加
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" 
    rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" 
    crossorigin="anonymous">

    <title>{% block title %}{% endblock title %}| 本棚アプリケーション</title>
      <link rel="stylesheet" type="text/css" href="{% static 'book/css/style.css' %}"> # 追加
    </head>

cssの利用には{% load static %}と{% static 'book/css/style.css' %}でbookproject/book/static/book/css/style.cssにあるcssファイルを呼び出して使います。
ではその場所にstyle.cssを作成します。

mkdir book/static
mkdir book/static/book
mkdir book/static/book/css
mkdir book/static/book/css/style.css

作成したstyle.cssに以下の記述をします。これはaタグの下線を消すコードです。

a {
    text-decoration: none;
}

これでcssの設定ができました。


おわりに

今回は、本に合わせた画像の表示とcssの設定を行いました。
次回は画像を利用してユーザーが本の投稿や削除をできるようにしていきます。