Django DeleteView не производит удаление
Я хочу преобразовать удаление пользователя из FBV в CBV
Мой FBV
def delete_student(request, pk):
student = get_object_or_404(Student, pk=pk)
student.delete()
return HttpResponseRedirect(reverse("students:get_students"))
Мое CBV
class DeleteStudentView(DeleteView):
model = Student
form_class = StudentForm
template_name = "students/students_list.html"
success_url = reverse_lazy("students:get_students")
student_list.html
<td><a type="button" class="btn btn-danger"
href="{% url 'students:delete_student' student.pk %}">Delete</a>
</td>
Ошибки нет, но выбор не происходит. В чем может быть проблема?
A DeleteView
удаляется с помощью запроса POST или DELETE. Это обязательно по спецификациям протокола HTTP. Ваш FBV не соответствует протоколу HTTP.
Для этого вам нужно сделать мини-форму. Например, сделайте скрытую форму с:
<td><button class="btn btn-danger" onclick="delete_item({{ student.pk }});">Delete</button></td> <!-- … --> <form method="post" action="{% url 'students:delete_student' %}" id="delete_form"> {% csrf_token %} <input type="hidden" name="pk" id="delete_pk"> </form> <script> function delete_item(pk) { var hidden_item = document.getElementById("delete_pk"); hidden_item.value = pk; var form = document.getElementById("delete_form"); form.submit(); } </script>
В urls.py
определяем запись для StudentDeleteView
без параметров:
# students/urls.py
from django.urls import path
app_name = 'students'
urlpatterns = [
# …
path('student/delete/', StudentDeleteView.as_view(), 'delete_student'),
# …
]
В DeleteView
вы затем определяете объект с первичным ключом:
from django.shortcuts import get_object_or_404
class DeleteStudentView(DeleteView):
model = Student
success_url = reverse_lazy('students:get_students')
def get_object(self, *args, **kwargs):
return get_object_or_404(Student, pk=self.request.POST.get('pk'))
Чтобы сделать ваше представление на основе функций совместимым с HTTP, вы должны обеспечить, чтобы оно могло делать это только при запросе POST или DELETE, например, с помощью декоратора @require_http_methods(…)
[Django-doc]:
from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_http_methods
@require_http_methods(["DELETE", "POST"])
def delete_student(request):
student = get_object_or_404(Student, pk=request.POST.get('pk'))
student.delete()
return redirect('students:get_students')
и таким образом использовать тот же "трюк" с мини-формой.