Django: views.generic.edit.BaseDeleteView を使って、もっとスマートにオブジェクトを削除しよう!


django.views.generic.edit.BaseDeleteView は、Django のジェネリックビューの一つで、オブジェクトの削除処理を簡潔に行うための基底クラスです。直接使用することは想定されておらず、サブクラスとして継承して使用する必要があります。

主な機能

  • 削除成功・失敗時の処理
  • 削除確認画面の表示
  • オブジェクトの削除処理を自動的に行う

使い方

  1. BaseDeleteView を継承するサブクラスを作成する
  2. 必要な属性を設定する
  3. ビューをURLパターンに登録する

属性

  • template_name_suffix: 削除確認画面のテンプレート名サフィックス
  • success_message: 削除成功時のメッセージ
  • success_url: 削除成功後のリダイレクト先URL
  • template_name: 削除確認画面のテンプレート名
  • model: 削除対象のモデルクラス

メソッド

  • get_context_data(): 削除確認画面のコンテキストデータを返す
  • get_success_url(): 削除成功後のリダイレクト先URLを返す
  • delete_object(object): オブジェクトを削除する
  • get_object(): 削除対象のオブジェクトを取得する
from django.views.generic.edit import BaseDeleteView

from .models import MyModel

class MyDeleteView(BaseDeleteView):
    model = MyModel
    template_name = 'my_app/my_delete_view.html'
    success_url = '/'
    success_message = '削除が完了しました。'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['object'] = self.object
        return context
  • 削除処理のロジックをカスタマイズしたい場合は、delete_object() メソッドをオーバーライドできます。
  • 削除成功・失敗時のメッセージは、テンプレートで表示できます。
  • 削除確認画面には、削除対象オブジェクトの情報が表示されます。


from django.shortcuts import render
from django.urls import reverse
from django.views.generic import ListView, DeleteView
from .models import Book

class BookListView(ListView):
    model = Book

class BookDeleteView(DeleteView):
    model = Book
    success_url = reverse_lazy('book_list')

This code will create two views:

  • BookDeleteView: This view will allow users to delete a book from the library.
  • BookListView: This view will display a list of all the books in the library.

To use these views, you will need to add them to your URL patterns. For example:

from django.urls import path
from .views import BookListView, BookDeleteView

urlpatterns = [
    path('books/', BookListView.as_view(), name='book_list'),
    path('books/<int:pk>/delete/', BookDeleteView.as_view(), name='book_delete'),
]

This will create two URLs:

  • /books/<int:pk>/delete/: This URL will allow users to delete a book with the specified primary key (pk).
  • /books/: This URL will display the list of books.

To delete a book, a user can click on the "Delete" link next to the book they want to delete. This will take them to the /books/<int:pk>/delete/ URL, where they will be shown a confirmation page. If the user clicks on the "Delete" button on the confirmation page, the book will be deleted and they will be redirected to the /books/ URL.

Here is an example of the book_delete.html template that could be used to display the confirmation page:

{% extends 'base.html' %}

{% block content %}
<h1>削除確認</h1>

<p>この本を削除しますか?</p>

<p><strong>{{ book.title }}</strong></p>

<form method="post">
    {% csrf_token %}
    <button type="submit">削除</button>
</form>

<a href="{% url 'book_list' %}">キャンセル</a>
{% endblock %}

This template will display the title of the book that is being deleted and a form with a "Delete" button. If the user clicks on the "Delete" button, the form will be submitted to the /books/<int:pk>/delete/ URL, and the book will be deleted.



代替方法の例

  • 手動でビューを作成する

BaseDeleteView を継承せずに、手動でビューを作成することもできます。この方法では、削除処理のロジックをより細かく制御できます。

from django.shortcuts import render, redirect
from django.http import HttpResponseNotFound
from .models import MyModel

def my_delete_view(request, pk):
    try:
        object = MyModel.objects.get(pk=pk)
    except MyModel.DoesNotExist:
        return HttpResponseNotFound('オブジェクトが見つかりません。')

    if request.method == 'POST':
        object.delete()
        return redirect('/success/')

    context = {
        'object': object,
    }
    return render(request, 'my_app/my_delete_view.html', context)
  • FormView と組み合わせる

FormView と組み合わせることで、削除処理の前にフォームによる入力チェックやバリデーションを行うことができます。

from django.forms import ModelForm
from django.views.generic import FormView
from .models import MyModel

class MyDeleteForm(ModelForm):
    class Meta:
        model = MyModel
        fields = []

class MyDeleteView(FormView):
    model = MyModel
    form_class = MyDeleteForm
    template_name = 'my_app/my_delete_view.html'
    success_url = '/'

    def form_valid(self, form):
        form.instance.delete()
        return super().form_valid(form)
  • JavaScript を使用する

JavaScript を使用して、AJAX リクエストでオブジェクトを削除することもできます。

function deleteObject(pk) {
    $.ajax({
        url: '/my_app/my_delete_view/' + pk + '/',
        method: 'POST',
        success: function() {
            // 削除成功時の処理
        },
        error: function(xhr, status, error) {
            // 削除失敗時の処理
        }
    });
}
方法利点欠点
BaseDeleteView簡潔で使いやすい削除処理のロジックを細かく制御できない
手動でビューを作成する削除処理のロジックを細かく制御できるコード量が多くなる
FormView と組み合わせる削除処理の前にフォームによる入力チェックやバリデーションを行うことができるコード量が多くなる
JavaScript を使用する非同期で削除処理を行うことができるJavaScript の知識が必要