0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Progateで作ったWebアプリをDjangoで作ってみる! Part7 -Delete編-

Last updated at Posted at 2021-07-22

ProgateのNode.jsコースではお買い物リストアプリを作るのですが、これと全く同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

目標物
image.png

HTMLとCSS、PNG形式画像は使い回しで、一部をDjango用のタグに変えます。

#前回のおさらい

Part6

Part6では、リストのアイテムをブラウザから編集・更新できるページを作成しました。

今回はリストを削除するための機能を実装していきます。

#Delete機能の実装

Deleteの実装方法は、削除するメモを指定して、deleteメソッドを使うだけです。なのでページを表示する必要はないのでテンプレートを用意する必要はありません。

Djangoは削除用のビューとしてDeleteViewを準備してくれていますが、今回はそれを使いません。Listページの「削除」をクリックするだけでアイテムを消せるようにします。

☆1のようにhref="{% url 'list:edit' object.pk %}とすることで、http://localhost:8000/delete/(数字)にアクセスしたとき、primary keyが(数字)のものが削除されるようにします。削除用のdelete関数をviews.pyで定義していきます。

index.html
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>LIST APP</title>
    <link rel="stylesheet" href="{% static 'list/style.css' %}">
  </head>
  <body>
    <header>
      <a href="{% url 'list:top' %}" class="header-logo">LIST APP</a>
    </header>
    <div class="container">
      <div class="container-header"> 
        <h1>買い物リスト</h1>
        <a href="{% url 'list:new' %}" class="new-button">+ 新規登録</a>
      </div>
      <div class="index-table-wrapper">
        <div class="table-head">
          <span class="id-column">ID</span>
          <span>買うもの</span>
        </div>
        <ul class="table-body">
          {% for object in object_list %}
            <li>
              <div class="item-data">
                <span class="id-column">{{ forloop.counter }}</span>
                <span class="name-column">{{ object.item }}</span>
              </div>
              <div class="item-menu">
                <form action="{% url 'list:delete' object.pk %}" method="post">{% csrf_token %}
                  <input type="submit" value="削除">
                </form>
                <a href="{% url 'list:edit' object.pk %}">編集</a> <!--☆1-->
              </div>
            </li>
          {% endfor %}
        </ul>
      </div>
    </div>
  </body>
</html>

delete関数の実装をやっていきます。

関数名はdeletefuncとします(☆2)。引数はrequestpk(primary key)とします。

**get_object_or_404()関数とredirect()**関数を使うため、あらかじめimportしておきます(☆3)。

**deletefunc()関数内で、はじめにget_object_or_404()**関数を使って、データベース(ListModel)のidpkのアイテムをgetします。そして、それを変数itemに代入します(☆4)。

そのitemを**delete()**メソッドで削除します(☆5)。

削除したあとは、Listページにリダイレクトするようにします(☆6)。

@require_POSTというものがimportされ、関数の頭に追加されています(☆7)。これによって、postの時のみこの関数が実行され、getのときは実行されなくなります(☆7)。

listapp/list/views.py
from django.shortcuts import render, redirect, get_object_or_404 # ☆3
from django.views.generic import TemplateView, ListView, CreateView, UpdateView
from .models import ListModel 
from django.urls import reverse_lazy
from django.views.decorators.http import require_POST # ☆7

class ListTop(TemplateView):
    # top.htmlをレンダリング
    template_name = 'list/top.html'

class ListIndex(ListView):
    # index.htmlをレンダリング
    template_name = 'list/index.html'
    model = ListModel

class ListNew(CreateView):
    # new.htmlをレンダリング
    template_name = 'list/new.html'
    model = ListModel
    fields = ['item']
    success_url = reverse_lazy('list:index')

class ListEdit(UpdateView):
    # edit.htmlをレンダリング
    template_name = 'list/edit.html'
    model = ListModel
    fields = ['item']
    success_url = reverse_lazy('list:index')

@require_POST # ☆7
def deletefunc(request, pk): # ☆2
    item = get_object_or_404(ListModel, id=pk) # ☆4
    item.delete() # ☆5
    return redirect('list:index') # ☆6

最後に、urls.pyファイルにコードを追加して、views.pydeletefunc関数を読み込むようにします。

listapp/list/urls.py
from django.urls import path
from .views import ListTop, ListIndex, ListNew, ListEdit, deletefunc # ☆8

# URLパターンを逆引きできるように名前をつける
app_name = 'list'

urlpatterns = [

    # リクエストされたパス部分が''に合致した場合、views.pyのListTopクラスをインスタンス化する
    path('', ListTop.as_view(), name='top'),

    # リクエストされたパス部分が'index'に合致した場合、views.pyのListIndexクラスをインスタンス化する
    path('index/', ListIndex.as_view(), name='index'),

    # リクエストされたパス部分が'new'に合致した場合、views.pyのListNewクラスをインスタンス化する
    path('new/', ListNew.as_view(), name='new'),

    # リクエストされたパス部分が'edit/pk'に合致した場合、views.pyのListEditクラスをインスタンス化する
    path('edit/<int:pk>', ListEdit.as_view(), name='edit'),

    # リクエストされたパス部分が'delete/pk'に合致した場合、views.pyのdeletefuncを呼び出す
    path('delete/<int:pk>', deletefunc, name='delete'), # ☆8
]

実際に「削除」ボタンで削除されるか確かめてみましょう。

image.png

image.png

ちゃんと「削除」ボタンで削除されました!

これで全て完成です!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?