Todo List - 투두리스트 삭제 기능 구현
투두 리스트 삭제 기능을 추가해 보려 합니다.
삭제 버튼은, 투두리스트 페이지와,
투두리스트 디테일 페이지에 추가해 줄겁니다.
DeleteView 를 사용하기 때문에,
삭제 버튼을 누르면, ‘정말 삭제하겠습니까?’ 라는 문구를 가진 컨펌 페이지가 뜨고,
한번 더 삭제하기 버튼을 누르면,
삭제가 완료되고.
취소 버튼을 누르면, 다시 투두리스트 리스트 페이지로 가게 됩니다.
DeleteView 는 클래스 기반 뷰로,
기본적으로, 정말로 삭제할것인지에 대한 컨펌 페이지를 가지고 있어서
삭제 버튼을 눌렀을때, 이 컨펌 페이지를 거쳐서 삭제를 눌러야
객체가 삭제 됩니다.
구현 과정은 아래와 같습니다.
todo/views.py 파일에 DeleteView 클래스를 추가
templates/todo/delete.html 파일 생성및 작성
templates/todo/todolist_list.html 파일 수정 (삭제버튼 설정)
templates/todo/todolist_detail.html 파일 수정 (삭제버튼 설정)
todo/urls.py 파일에서 delete URL 설정
todo/views.py 파일에 DeleteView 클래스 추가
1 2 3 4
| class DeleteView(generic.DeleteView): model = TodoList success_url = '/' tempalte_name = 'todo/delete.html'
|
templates/todo/delete.html 파일 생성 및 작성
1 2 3 4 5 6
| base.html 상속받는 대신에, {% load static %} 을 사용하여, static 폴더 안에 있는 style.css 파일을 직접 가져와 사용했습니다.
DeleteView 를 사용하기 때문에, {{ form }} 을 사용하여, 삭제 폼을 만들어 주었고,
삭제 버튼과 취소 버튼을 만들어 주었습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| {% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bulma/css/style.css' %}">
<div class="field is-grouped is-grouped-centered"> <p>{{ object }}</p><br><br> </div>
<div class="field is-grouped is-grouped-centered"> <form action="" method="POST"> {{ form }} {% csrf_token %}
<p class="control"> <input type="submit" class="button is-danger" value="삭제"> <a class="button is-light" href="{% url 'todo:todolist' %}"> 취소 </a> </p> </form> </div>
<div class="field is-grouped is-grouped-centered"> <p class="control"> 해당 투두리스트를 삭제 하시겠습니까? </p> </div>
|
templates/todo/todolist_list.html 파일 수정
1 2 3 4 5 6 7 8
| 삭제하기 버튼을 누르면, "/delete/{{ todo.id }}" url 로 넘어가서, DeleteView 를 호출할것입니다.
<footer class="card-footer"> <a href="/detail/{{ todo.id }}" class="card-footer-item"><button class="button is-primary is-fullwidth">더보기</button></a> <a href="#" class="card-footer-item"><button class="button is-warning is-fullwidth">수정하기</button></a> <a href="/delete/{{ todo.id }}" class="card-footer-item"><button class="button is-danger is-fullwidth">삭제하기</button></a> </footer>
|
templates/todo/todolist_detail.html 파일 수정
1 2 3 4 5 6 7 8 9 10
| 삭제하기 버튼을 누르면, "/delete/{{ todo.id }}" url 로 넘어가서, DeleteView 를 호출하게 해서,
Detail 페이지에서도 삭제가 가능하게 하려 했지만,
DeleteView 를 Detail 페이지에서 호출하면, 에러가 납니다. (이에 대한 해결 방법을 찾지 못하고 있음)
따라서, 삭제 버튼을 누르면, 다시 리스트 페이지로 되돌아오게 해주었습니다..
|
1 2 3 4 5
| <footer class="card-footer"> <a href="{% url 'todo:todolist' %}" class="card-footer-item"><button class="button is-link is-fullwidth">뒤로가기</button></a> <a href="#" class="card-footer-item"><button class="button is-warning is-fullwidth">수정하기</button></a> <a href="{% url 'todo:todolist' %}" class="card-footer-item"><button class="button is-danger is-fullwidth">삭제하기</button></a> </footer>
|
todo/urls.py 파일에서 delete URL 설정
‘delete/int:pk/‘ 라는 URL 을 가지면, DeleteView 를 호출하고,
삭제 페이지로 넘어가게 됩니다.
1 2 3 4 5 6 7 8 9 10 11
| from django.contrib import admin from django.urls import path from .views import IndexView, DetailView, DeleteView
app_name = 'todo'
urlpatterns = [ path('', IndexView.as_view(), name='todolist'), path('detail/<int:pk>/', DetailView.as_view(), name="todolist_detail"), path('delete/<int:pk>/', DeleteView.as_view(), name="todolist_delete"), ]
|
마치며..
서버를 시작하고, 삭제 테스트를 해봅니다.
투두 리스트 페이지에서 삭제 진행
삭제 버튼을 누르면, 아래 컨펌 페이지가 뜨고, 여기서 한번 더 삭제를 누르면 객체가 삭제 완료 됩니다.
삭제 버튼을 누르면, 투두리스트 삭제가 진행 되는것을 확인 하였습니다만.
디테일 페이지에서 삭제 동작을 구현하지 못한것이 아쉽습니다.
클래스 베이스 뷰에 있는 DeleteView 를 더 많이 경험해 봐야 알것 같습니다.
만약, DeleteView 를 사용하지 않고, 함수형으로 이 기능을 구현하고 싶다면,
views.py 에 아래와 같은 함수를 작성하고, 적절히 URL 을 연결하여 사용하면 됩니다.
1 2 3 4 5
| def delete_todo(request, pk): t = TodoList.objects.get(pk=pk) t.delete() return redirect('/')
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from django.contrib import admin from django.urls import path from .views import IndexView, DetailView, DeleteView, UpdateView, TodoCreate from .views import delete_todo app_name = 'todo'
urlpatterns = [ path('', IndexView.as_view(), name='todolist'), path('detail/<int:pk>/', DetailView.as_view(), name="todolist_detail"), path('delete/<int:pk>/', DeleteView.as_view(), name="todolist_delete"), path('delete_todo/<int:pk>/', delete_todo, name="delete_todo"), path('update/<int:pk>/', UpdateView.as_view(), name='todolist_update'), path('create/', TodoCreate, name='todolist_create'), ]
|
다만, 이렇게 구현 하면, DeleteView 를 사용했을때랑은 다르게,
Confirm page 가 나오지 않고. 바로 삭제가 됩니다.