I'm using Django 1.10.6 and I'm using a class-based view DeleteView.
Example 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')
Example 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>
Because deleting is a serious operation, I want to add more robust confirmation such that the user needs to type the author name in before the author can be deleted (and it must match. similar to the github confirmation for deleting repositories). I guess this might be implemented as some kind of form validation.
What's the django-way to add this type of confirmation?
I would create a Django ModelForm, it could then compare a separate HTML input field to the model instance field. In the view, if the form validation fails... the delete doesn't happen.
# 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>