本に合わせた画像を表示させる
はじめに
前回の続きで、今回は本に合わせて画像を表示させることを行います。
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の設定を行いました。
次回は画像を利用してユーザーが本の投稿や削除をできるようにしていきます。