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 클래스 추가
| 12
 3
 4
 
 | class DeleteView(generic.DeleteView):model = TodoList
 success_url = '/'
 tempalte_name = 'todo/delete.html'
 
 | 
templates/todo/delete.html 파일 생성 및 작성
| 12
 3
 4
 5
 6
 
 | base.html 상속받는 대신에, {% load static %} 을 사용하여, static 폴더 안에 있는 style.css 파일을 직접 가져와 사용했습니다.
 
 DeleteView 를 사용하기 때문에, {{ form }} 을 사용하여, 삭제 폼을 만들어 주었고,
 
 삭제 버튼과 취소 버튼을 만들어 주었습니다.
 
 | 
| 12
 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 파일 수정
| 12
 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 파일 수정
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 삭제하기 버튼을 누르면, "/delete/{{ todo.id }}" url 로 넘어가서, DeleteView 를 호출하게 해서,
 
 
 Detail 페이지에서도 삭제가 가능하게 하려 했지만,
 
 
 DeleteView 를 Detail 페이지에서 호출하면, 에러가 납니다. (이에 대한 해결 방법을 찾지 못하고 있음)
 
 따라서, 삭제 버튼을 누르면, 다시 리스트 페이지로 되돌아오게 해주었습니다..
 
 | 
| 12
 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 를 호출하고, 
삭제 페이지로 넘어가게 됩니다. 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | from django.contrib import adminfrom 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 을 연결하여 사용하면 됩니다. 
| 12
 3
 4
 5
 
 | def delete_todo(request, pk):
 t = TodoList.objects.get(pk=pk)
 t.delete()
 return redirect('/')
 
 | 
| 12
 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 가 나오지 않고. 바로 삭제가 됩니다.