CRUDを実装する(CRUDのCUD)

はじめに

以前↓にCRUDのRは作成しました。今回はその他を作成していきます。
urhayataro.hatenablog.com

まず復習から、CRUDとは

  • C-作成
  • R-読み取り
  • U-更新
  • D-削除

でした。また、対応するViewは

  • C - CreateView
  • R - ListView, DetailView
  • U - UpdateView
  • D - DeleteView

です。この中のC,U,Dを作成していきます。
今回も触るファイルは主に、urls.py、views.py、そして各htmlファイルです。


CreateViewの作成

CreateViewで実装するのは、ブラウザ上でデータの作成をするためのものです。ブラウザ上で入力したデータをデータベースに追加するためのプログラムを組んでいきます。

まずはbook/urls.pyから以下の記述をします。

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.ListBookView.as_view(), name='detail-book'),
    path('book/create/', views.CreateBookView.as_view(), name='create-book'),
]

そして、追加したurlpetternsに対応させるようにbook/views.pyも記述をしていきます。

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

# Create your views here.
class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

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

ここで追加した最後の行のfieldsはブラウザで表示する項目を表しています。CreateViewを使うときには、modelのどの項目を表示させるかをviewの中で指定する必要があります。

これができればcreateのページを作るためのhtmlファイルを作成します。

touch book/templates/book/book_create.html

作成したbook_create.htmlに以下を記述します。

{% extends 'base.html' %}

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

{% block content %}
    <form method='POST'>
        {{form.as_p}}
        <input type='submit' value='作成する'>
    </form>
{% endblock content %}

これで一度サーバーを立ち上げ127.0.0.1:8000/book/create/にアクセスします。すると以下のような入力画面が表示されます。

適当に投稿してみると、CSRFが発行されていないというエラーが表示されます。CSRFはセキュリティ上の問題で、この対策としてDjangoではformにcsrf_tokenというタグを付けることとします。このcsrf_tokenはワンタイムパスワードのようなもので、持っていない状態では処理を行うことができません。

csrf_tokenのタグをbook/bookproject/book_create.htmlに以下を追加します。

{% extends 'base.html' %}

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

{% block content %}
    <form method='POST'>{% csrf_token %} # 追加
        {{form.as_p}}
        <input type='submit' value='作成する'>
    </form>
{% endblock content %}

これでcsrf_tokenの取得ができましたが、まだ「作成する」を押したときのurlの遷移先を設定していません。設定するにはform項目の作成が完了したときに指定のurlに遷移させるようにします。そのためにviewの中でsuccess_urlという変数を定義します。
book/views.pyに以下を追加します。

from django.shortcuts import render
from django.urls import reverse_lazy # 追加
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

# Create your views here.
class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

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

最後に追加したlist-bookについてurls.pyで指定したviews.pyの名前の設定をしていきます。また、list_book以外のurlpatternもnameの追加をしていきます。
book/urls.pyに以下を追加します。

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'), # 追加
    path('book/<int:pk>/detail', views.ListBookView.as_view(), name='detail-book'), # 追加
    path('book/create/', views.CreateBookView.as_view(), name='create-book'), # 追加
]

これでCreateViewの実装ができました。サーバーを立ち上げてデータの追加をすると、list-bookの画面に遷移し、データが追加されているはずです。



DeleteViewの作成

DeleteViewで実装するのは、データの削除をするためのものです。URLを使って削除するデータのidを指定し、リクエストを送るとデータベースが操作され削除されるという仕組みとなっています。

記述はほとんどCreateViewと同じで、urls.py、views.py、htmlに記述をしていきます。
まずはbook/urls.pyに以下の記述をします。

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.ListBookView.as_view(), name='detail-book'),
    path('book/create/', views.CreateBookView.as_view(), name='create-book'),
    path('book/<int:pk>/delete/', views.DeleteBookView.as_view(), name='delete-book'),
]

それからbook/views.pyにも記述をしていきます。

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView, CreateView, DeleteView,
from .models import Book

# Create your views here.
class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = {'title', 'text', 'category'}
    success_url = reverse_lazy('list-book')

class DeleteBookView(DeleteView):
    template_name = 'book/book_confirm_delete.html'
    model = Book
    success_url = reverse_lazy('list-book')

さらにhtml記述をします。

touch book/templates/book/book_confirm_delete.html

作成したbook_confirm_delete.htmlに以下を記述します。

{% extends 'base.html' %}

{% block title %}書籍削除{% endblock %}

{% block content %}
    <form method='post'>
        {% csrf_token %}
        <button type='submit'>{{ object.title }}を削除する</button>
    </form>
{% endblock %}

これでDeleteViewは実装できました。


UpdateViewの作成

CRUDの最後にUpdateの作成をしていきます。作成の目的としては、ブラウザ上でデータの編集をできるようにします。データの削除(D)から修正後を追加(C)ではなく、その場で編集ができるようにします。

作成するにあたって、これも基本的にCreateViewやDeleteViewと同じように、urls.py、views.py、htmlへの記述で作成していきます。

まずはbook/urls.pyに以下の記述をします。

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.ListBookView.as_view(), name='detail-book'),
    path('book/create/', views.CreateBookView.as_view(), name='create-book'),
    path('book/<int:pk>/delete/', views.DeleteBookView.as_view(), name='delete-book'),
    path('book/<int:pk>/update/', views.UpdateBookView.as_view(), name='update-book'),
]

そしてbook/views.pyにも以下の記述をします。

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import (ListView, DetailView, CreateView, DeleteView, UpdateView, )
from .models import Book

# Create your views here.
class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = {'title', 'text', 'category'}
    success_url = reverse_lazy('list-book')

class DeleteBookView(DeleteView):
    template_name = 'book/book_confirm_delete.html'
    model = Book
    success_url = reverse_lazy('list-book')

class UpdateBookView(UpdateView):
    template_name = 'book/book_update.html'
    model = Book
    fields = {'title', 'text', 'category'}
    success_url = reverse_lazy('list-book')

さらにhtmlファイルを追加し、記述をしていきます。

touch book/templates/book/book_update.html

作成したbook_update.htmlに以下の記述をします。

{% extends 'base.html' %}

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

{% block content %}
    <form method='post'>{% csrf_token %}
        {{ form.as_p }}
        <button type='submit'>修正する</button>
    </form>
{% endblock %}

これでUpdateViewの実装もできました。
ここまででCRUDの実装がすべてできました。


おわりに

今回はCRUDのC、U、Dの作成をしました。どれもviews.py、urls.py、htmlの記述で実装できることがわかりました。
今のところurlを直接打ってアクセスしているので、次回はブラウザ上でボタンのクリックで画面を遷移させていきます。