Django

Django 簡単なアプリを作って基礎を覚える⑪ 画像を登録・表示する

今回は、画像ファイルを取り扱ってみましょう❕

まずは、画像を保存するためのフィールドを作成しましょう😀

画像ファイルを登録・表示する

ホームページ制作にチャレンジしよう

models.pyにフィールドを追加

from django.db import models
from accounts.models import CustomUser

class TaskModel(models.Model):
    title = models.CharField(verbose_name='タイトル', max_length=100,  null=True)
    memo = models.TextField(verbose_name='内容', blank=True, null=True)
    image = models.ImageField(upload_to='')#細かい保存場所を指定するときは、指定する。指定しなければ、settingsファイルの設定値
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name='担当者',blank=True, null=True)
    plants_startdate = models.DateField(verbose_name='開始予定日', blank=True, null=True)
    plants_enddate = models.DateField(verbose_name='終了予定日', blank=True, null=True)

    def __str__(self):
        return self.title

これで、画像ファイルを保存するフィールドを指定できました。

細かく保存先を設定する場合は、upload_to で階層を指定しましょう。

テーブルの設定を変更した時は、migrations ⇒ migrate をしましょう🙂

migrationsを実行

python manage.py makemigrations #実行命令
You are trying to add a non-nullable field 'image' to taskmodel without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
Select an option: 

実行すると、上記のような確認がされます。確認の内容は、

不可能なフィールド「image」をデフォルトなしでtaskmodelに追加しようとしています。それはできません(データベースには既存の行にデータを入力するための何かが必要です)。
修正を選択してください:
 1)今すぐ1回限りのデフォルトを提供します(この列の値がnullの既存のすべての行に設定されます)
 2)終了し、models.pyにデフォルトを追加さ​​せてください
選択肢一つを選択してください:

今回は、既存のレコードには、とくに何もする必要がないので’’空にしましょう。

「1」を入力してエンターを押下します。

オプションを選択してください:1
有効なPythonとして、今すぐデフォルト値を入力してください
datetimeモジュールとdjango.utils.timezoneモジュールが利用できるので、たとえば次のことができます。 timezone.now
'exit'と入力して、このプロンプトを終了します

初期値をすべてに入れることができますよ。例えば、timezoneっていれると、今の時間を入れてくれるということです。

今回は、’’空を指定してみましょう。

''
Migrations for 'task':
task\migrations
''
Migrations for 'task':
task\migrations\0002_taskmodel_image.py
- Add field image to taskmodel
PS C:\Users\hdj16\Desktop\Test>
02_taskmodel_image.py - Add field image to taskmodel PS C:\Users\hdj16\Desktop\Test>

migrateを実行

続いて、migrateします。

PS C:\Users\hdj16\Desktop\Test> python manage.py migrate
Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, sessions, task
Running migrations:
  Applying task.0002_taskmodel_image... OK
PS C:\Users\hdj16\Desktop\Test> 

サーバー起動してみよう

python manage.py runserver

管理サイトで、taskの詳細を見てみましょう!

イメージファイルを選択するためのボタンが用意されていることがわかります😀

ただ、これだけでは設定が足りません。

settings.pyを登録する

settingsファイルにメディアを基本どこに保存するのかと、メディアへのルートを設定します。

LOGIN_REDIRECT_URL='/task/list/'
AUTH_USER_MODEL = 'accounts.CustomUser'

#追加
MEDIA_LOOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

一番下にメディアの保存場所とURLを指定します。

メディアを保存するフォルダを作成

settingsファイルで、先ほど指定したMEDIA_LOOTであるフォルダ、mediaを作成します。

プロジェクト直下urls.pyにメディアファイルの情報指示をだすようにする

あとは、実際の指示を出すurl.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('accounts/', include('django.contrib.auth.urls')),
    path('task/', include('task.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

task.urls.pyも修正

task アプリのviewsを修正しよう!

それでは、task

管理サイトで保存してみましょう❕

ファイルが保存されているように見えます。クリックして実際に開くかどうか確認しみましょう❕

画像が開かれました😄

create、update、deleteのhtmlファイルを修正する

htmlファイルをこのままだと、新規登録や更新しても画像がアップされません。

そのために、少し修正します。

{% extends 'templates/base.html' %}


{% block title %}
{% endblock title %}

{% block header %}
{% endblock header %}

{% block content %}
<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
    {{form.as_p}}
    <a href="{% url 'task:list' %}" button type="button" class="btn btn-secondary">戻る</a>
    <input type="submit"  class="btn btn-primary" value="作成">
</form>
{% endblock content %}

form action の行に、 enctype="multipart/form-data" を追加することで、画像ファイルが保存されるようになります。

update,htmlにも同じく追加します。

{% extends 'templates/base.html' %}


{% block title %}
{% endblock title %}

{% block header %}
{% endblock header %}

{% block content %}
<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
    {{form.as_p}}
    <a href="{% url 'task:list' %}" button type="button" class="btn btn-secondary">戻る</a>
    <input type="submit"  class="btn btn-primary" value="更新">
</form>
{% endblock content %}

実際登録できるかやってみましょ!

新規登録をしてみる

新規登録画面から実際登録をしてみます。

ファイルを選択するとファイル名が表示されます。

作成ボタンを押下すると、mediaファイルにファイルが保存されます。

保存場所をmodelsで指定していないので、mediaフォルダの直下に保存されています。

修正画面で修正できるかやってみましょう。

修正画面で削除と登録をしてみる

まずは、ファイル名をクリックをしてファイルが起動できるかしてみましょう。

無事に表示できると思います😀

クリアのチェックボックスを利用して削除してみよう

クリアにチェックを入れる

チェックを入れて更新してみましょう。

もう一度開くと、ファイル名が表示されなくなっています。

mediaフォルダの直下には、ファイルは残っていますが、ファイル名が消えます。

違うファイルを選択して更新してみましょう。

これで、更新ができます。

再度開くと、ファイル名が変わっていて、メディアファイルの直下にファイルが増えています。

これで、画像ファイルの取り扱いは終了です🙂

-Django

© 2021 ごろう@縁紡ぐ