• 商品一覧
  • お問合せ
  • ブログ記事
お仕事の依頼
好かれるマーケティング研究室のデフォルトサムネイル画像

DjangoでCRUD対応をする

2021-04-03
前回の記事では、モデルを作成して、そのモデルの全てデータの一覧を取得する部分までを作成しました。
この記事ではCreate(作成)、Read(詳細)、Update(更新)、Delete(削除)の部分を実装していきます。
ここまで作成することができれば、Django初心者を卒業したと言ってもいいでしょう!それでは始めていきましょう。

DjangoでのCreateの実装

前回の記事でほとんどクラス名だけ書いていたskills/views.pyのSkillCreateViewクラスを実装していきます。
# skills/views.py

from django.views import generic
from .models import Skill
from django.urls import reverse_lazy

class SkillCreateView(generic.CreateView):
  model = Skill
  template_name = 'skills/create.html'
    
  fields = '__all__'
  success_url = reverse_lazy('skills:list')
フォームからSkillモデルの作成に必要な情報を入力してもらって、その情報をもとに、Skillのデータを作成することになります。fields変数には、このフォームで入力して欲しいSkillモデルのフィールドを選択します。
Skillモデルにはnameとdescriptionのフィールドがあり、全部入力して欲しい場合は、'all'とします。もし、フィールドの一部に限定したいのであれば、それらをリストにします。例えば、nameだけにしたいのであれば、['name']となります。
次に、success_urlではSkillデータの作成が終わったら、どのページに遷移するかを指定しています。ここでは、skillsアプリケーションの一覧ビューに遷移するようにしました。
これだけで終わりです。モデルの情報をそのまま入れてもらうだけなら、非常に簡単に作れます。​
もしモデルをデータベースに書き込む前に、何か変更を加えたいのであれば、[form_valid]関数を実装すると良いです。[form_valid]関数はフォームの入力内容に問題がなかったら、呼ばれる関数です。使う場合は、SkillCreateViewクラスに以下の関数を追加します。
def form_valid(self,form):
  skill = form.save(commit=False)
  skill.name = "スキル"
  skill.save()
  return super().form_valid(form)
[form.save]でcommit=Falseにすると、データベースに保存せずに、フォームから作成したモデルを取得できます。そして、モデルの内容を変更し、save()を呼ぶことで、変更した内容でデータベースに保管できます。
つまり、この実装でSkillデータを作成すると、全てのスキルの名前が"スキル"になってしまいます。そのため、この関数は消しておきます。
さて、後はこのViewのテンプレートである"skills/create.html"の作成だけです。
# skills/create.html

<!DOCTYPE html>
<html>
 <header>
   <title>Skill作成ページ</title>
 </header>
 <body>
   <div>Skillの情報を入力してください</div>
   <form method="post">
     {% csrf_token %}
     {{ form.as_p }}
     <button type="submit">作成</button> 
   </form>
 <body>
</html>
[form.as_p]と書くことで、formの各項目を<p>タグで囲むことができます。問い合わせのページで作成したテンプレートとすごく似ていますね。
それでは、これでSkillのCreate機能が完了しましたので、実際にデータベースにデータを追加してみましょう!
python manage.py runserver
http://localhost:8000/skills/create/
フォームに情報を入力して[作成]ボタンを押す
Django CreateViewで作成したform
Skillの一覧ページに、スキル名が表示されれば成功です!
Django スキル作成後のlist画面
どうでしたか、意外と簡単にデータを追加できたのではないでしょうか?
それでは、どんどん作成していきましょう。続いては、このスキルの詳細表示ページです。

DjangoのRead(詳細(Detail))ページの作成

モデルの詳細ページを作成していきます。
詳細ページを作成することで、Skill1つ1つの詳しい情報がみれるようになります。一覧では これまでSkillの名前しか表示されませんでしたが、詳細も確認したいことがあるかもしれません。
具体的な実装としては、先ほどのスキル一覧ページのスキル名に、詳細ページに移動するリンクを追加して、そのリンク先を表示するようにしましょう。
まずはViewの作成からです。
# skills/views.py

class SkillDetailView(generic.DetailView):
    model = Skill
    template_name = "skills/detail.html"
Createよりもさらに簡単ですね。2行しかありません。もう説明済みの内容しかないので次に進みます。
これをテンプレートで、情報を表示するようにしてあげましょう。
# skills/detail.html

<!DOCTYPE html>
<html>
  <header>
    <title>{{ object.name }}スキル</title>
  </header>
  <body>
    <p>{{ object.name }}</p>
    <p>{{ object.description }}</p>
  <body>
</html>
DetailViewでは、対象となるデータが1つしかないので、[object]変数でモデルのデータにアクセスすることができます。そこから[object.name]などとつけると、各フィールドの値を取得できます。
さて、DetailView自体はこれで完成ですが、Skillの一覧ビュー(ListView)からこのDetailViewにアクセスできるようにしたいですね。
現在のskills/list.htmlはこんな感じでした。
# skills/list.html

{% for skill in list %}
    {{ skill.name }} 
{% empty %}
    スキルがありません
{% end for %}
これにリンクを追加してあげます。
#skills/list.html

{% for skill in object_list %}
   <p>
     <a href="{% url 'skills:detail' skill.pk %}">{{ skill.name }} </a>
   </p>
{% empty %}
   スキルがありません
{% endfor %}
HTMLでは、<a>タグでリンクを追加することができます。そして、hrefでリンク先をどこにするか指定しています。ただし、このリンク先の記入方法はDjango特有の書き方です。
"{% url 'skills:detail' skill.pk %}"のurlテンプレートタグでアドレスを指定しています。こうすることで、リンク先をreverse_lazyで使っているような形式[app_name:name]で書くことができます。
具体的にアドレスを書かなくても、わかりやすい名前を書くだけでアドレスが指定できるのでちょっと楽になります。
そして、DetailViewのpathには<int:pk>があったのを思い出してください。
  path("<int:pk>/", views.SkillDetailView.as_view(),name="detail"),
リンク先を指定するには、ここに何を入れたらいいか、教えてあげる必要があります。Skillモデルのprimary keyを指定すればいいので、skill.pkと書くことができます。​
さあ、これでSkillの詳細画面も完成しました。開発用サーバーを立ち上げて、問題なく動くか確認してみましょう。
python manage.py runserver
各Skillがリンクになっているので、それをクリック
Django list画面にスキルのリンク追加
Skill詳細ページが表示される
Django スキル詳細ページ
どうでしたか?これで詳細ページも完成したので、後は更新と削除だけですね。半分完了したので、もうちょっとです!

DjangoでUpdate(更新)ページを作成する

それではスキルの更新ページを作成しましょう。このページは今までの2つの作成方法を理解できていれば、全く難しくありません。CreateとDetailのViewを合わせたような感じになります。
まずは、Viewの作成から行っていきましょう。ここはCreateと同じようにフォームで更新する情報を取得していきます。ただし、更新を行った後は、その結果を確認したいので、更新成功後の遷移先を、スキルの詳細ビューに設定しましょう。
# skills/views.py

class SkillUpdateView(generic.UpdateView):
  model = Skill
  template_name = 'skills/update.html'
  
  fields = '__all__'

  def get_success_url(self):
    return reverse_lazy('skills:detail',kwargs={'pk':self.kwargs['pk']})
reverse_lazyで詳細ビューに遷移するように設定していますが、ここでも<int:pk>を設定する必要があります。それを設定している部分が、kwargs={'pk':self.kwargs['pk']}です。
少しずつ分けて説明しましょう。まずkwargsでは、辞書形式で複数の情報を渡すことができます。このようなパラメータを可変長変数といいます。例えば、2つの値を渡すとしたら{'pk':123,'name':'abc'}のようになります。このとき":"の左側の"pk"はキー(key)で":"の右側の123が値(value)になります。
渡された側では、kwargsのkeyを指定して、kwarg["pk"]などとすると、valueとして123が得られます。
同じような可変長変数であるargsは単純に("a","b")のようにタプルで情報を渡します。つまり、args[0]のようにアクセスして、"a"を取得できる形です。kwargsのほうが名前をつけて使えるので使いやすい印象です。
話を戻して、詳細ビューのアドレスは"<int:pk>/"となっていました。このpkが実はkwargsに既に入っています。それを継続して利用するために、再利用しています。
さて、それでは、最後にテンプレートを作成して、update画面を完成させましょう。このテンプレートはskills/create.htmlとほとんど変わりません。
# skills/update.html

<!DOCTYPE html>
<html>
  <header>
    <title>スキル更新ページ</title>
  </header>
  <body>
    <form method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">更新</button> 
    </form>
  <body>
</html>
また、詳細(Detail)ビューから更新(Update)ビューにアクセスできるようにリンクを追加しましょう。
# skills/detail.html

<!DOCTYPE html>
<html>
  <header>
    <title>{{ object.name }}スキル</title>
  </header>
  <body>
    <p>{{ object.name }}</p>
    <p>{{ object.description }}</p>
    <div><a href="{% url 'skills:update' object.pk %}">情報更新</a></div>
  <body>
</html>​
これで更新も実装できました。サーバーを起動して試してみてください。
python manage.py runserver
スキル名をクリックして詳細ページへ。
Django スキル詳細ページ+更新リンク
情報更新をクリックして更新ページへ。
Django スキル更新ページ
内容を変更して、更新ボタンを押す。
Django スキル更新後
いい感じですね!

DjangoでDelete(削除)のView作成

最後はDeleteのViewになります。簡単に削除できるようにしてしまうのは、Webアプリケーションとしてあまりよくないのですが、今回は普通に削除することにします。
実際の運用では、データベースから削除せずに、削除されましたと言うフラグを立てる論理削除がよく実行されます。なので実際はDeleteではなくて、Updateに近い処理になります。
とはいえ、実際に削除することもそれなりにあります。実装としては、スキルの詳細ビューから削除ビューに移動できるようにし、削除を実行やキャンセルした場合、スキルの一覧ビューに戻るようにしましょう。
まずはViewの実装からです。ほかのViewと特に変わりませんね。DeleteViewではフォームで送信するとモデルが削除されます。
# skills/views.py

class SkillDeleteView(generic.DeleteView):
  model = Skill
  template_name = 'skills/delete.html'
  success_url = reverse_lazy('skills:list')
これで後は、テンプレートを作成します。
#skills/delete.html

<!DOCTYPE html>
<html>
  <header>
    <title>スキル削除ページ</title>
  </header>
  <body>
    <p>{{ object.name }}を削除しますか?</p>
    <form method="post">
      {% csrf_token %}
      <button type="submit">削除</button> 
      <a href="{% url 'skills:detail' object.pk %}">キャンセル</a>
    </form>
  <body>
</html>
この削除ページには、詳細ページから飛びたいので、詳細ページにリンクを追加しましょう。
# skills/detail.html

<!DOCTYPE html>
<html>
 <header>
   <title>{{ object.name }}スキル</title>
 </header>
 <body>
   <p>{{ object.name }}</p>
   <p>{{ object.description }}</p>
   
   <div><a href="{% url 'skills:update' object.pk %}">情報更新</a></div>    
   <div><a href="{% url 'skills:delete' object.pk %}">削除</a></div>
 <body>
</html>
これでCRUD全ての実装が完了しました!
早速、開発用サーバーを起動して、ちゃんと動いているか確認してみてください!
python manage.py runserver
詳細ビューから削除をクリックして、削除ビューに移動
Django スキル詳細+削除リンク
キャンセルを押すと、詳細ビューに戻り、削除を押すとデータが削除されます。
Django スキル削除ページ
一覧からスキルがなくなったので、スキルがない時の表示になりました。
Django スキル削除後

サンプルサイト

repl.itにここまでに作成した内容を残しておきます。真ん中の再生ボタンを押すと、今回作成した部分を確認できます。ただし、データベースに関わる操作は反映されないので、Forkするかファイルをダウンロードしてあなた自身の環境で実施してください。
また、左側にあるCodeタブを選択すると、ファイル構成やファイルの内容を確認できます。

まとめ

CRUDの全てを実装しました。Create, Read, Update, Deleteの4つを作成することでそのモデルに必要な機能を全て実装することができました。
1つ作れるようになれば、他の処理も同じように作っていくことができるので、割と簡単に作れたのではないでしょうか。
ぜひ、自分で新しいモデルを作成して、面白いWebアプリケーションを作ってください!

練習問題

  1. 新しいモデルを作成してCRUDを全て実装してみましょう。
  2. Deleteで実際に削除せずに、論理削除できるようにしてみてください。
  3. 論理削除しても一覧に表示されていませんか?一覧に表示されないように変更してみてください。

無料メルマガ

今すぐもっと好かれる!

プロフィール

西松 大輝:マーケティング・サイエンティスト

数字から愛へ
・「何を変えるか?」を行動経済学・TOCLSSで分析する。
・「何を伝えるか?」を戦略・マーケティングで明確にする。
・「何を測定するか?」を機械学習・ITで支援する。

"全部"やらなくっちゃあならないってのが 「マーケティング・サイエンティスト」のつらいところだな。
覚悟はいいか?僕はできてる
  • お仕事の依頼
  • お問合せ
  • プライパシーポリシー
  • 特定商取引法に基づく表記
2019-2022, 好かれるマーケティング研究室©