基于Django class的DeleteView稳健确认?

Django class-based DeleteView robust confirmation?

我使用的是 Django 1.10.6,我使用的是基于 class 的视图 DeleteView。

示例myapp/views.py:

from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from myapp.models import Author

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

示例 myapp/author_confirm_delete.html:

<form action="" method="post">{% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    <input type="submit" value="Confirm" />
</form>

因为删除是一项严肃的操作,所以我想添加更可靠的确认,以便用户需要在删除作者之前输入作者姓名(并且必须匹配。类似于 github确认删除存储库)。我想这可能是作为某种表单验证来实现的。

添加此类确认的 django 方式是什么?

我会创建一个 Django ModelForm,然后它可以将一个单独的 HTML 输入字段与模型实例字段进行比较。在视图中,如果表单验证失败...删除不会发生。

# myapp/forms.py

from django import forms

class ConfirmDeleteForm(forms.ModelForm):
    confirm = forms.CharField(label='Confirm your name', max_length=100)

    class Meta:
        model = Author
        fields = []

    def clean(self):
        confirm = super().clean().get('confirm')

        if self.instance.name.lower() != confirm.lower():
            raise forms.ValidationError('Confirmation incorrect')

# myapp/views.py

from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from myapp.models import Author
from myapp.forms import ConfirmDeleteForm

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

    def get_context_data(self, **kwargs):
        """
        Overridden to add a confirmation form to the context.
        """
        context = super().get_context_data(**kwargs)

        if 'form' not in kwargs:
            context['form'] = ConfirmDeleteForm()

        return context

    def post(self, request, *args, **kwargs):
        """
        Overridden to process the confirmation form before deleting
        the object.
        """
        self.object = self.get_object()
        form = ConfirmDeleteForm(request.POST, instance=self.object)

        if form.is_valid():
            return self.delete(request, *args, **kwargs)
        else:
            return self.render_to_response(
                self.get_context_data(form=form),
            )

<!-- myapp/author_confirm_delete.html -->

<form method="post">
    {% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    {{ form }}
    <input type="submit" value="Confirm" />
</form>