8.班级管理的最后一块拼图:删除功能
到目前为止,其实你已经完成了一件非常不容易的事情:
- 班级能查
- 班级能加
- 班级能改
现在,就只剩下最后一个功能了。
也是很多新手最不敢点的那个按钮—— 👉 删除班级。
在正式写代码之前,可能你心里一定会冒出一个问题:
“万一一点就没了怎么办?”
所以,删除功能的第一原则只有一句话:
永远不要直接删,一定要先确认。
这一节,我们要做的,就是一个标准、专业、可控的删除流程。
1.删除功能的整体思路
在动手之前,我们先想清楚用户的操作路径:
- 在班级列表页点击「删除」
- 跳转到一个 确认页面
- 用户明确点击「确认删除」
- 才真正执行删除
- 删除完成后,回到列表页
只要你把这 5 步想清楚,后面的代码就一点都不难。

2.老规矩:先写 URL
回到 grades/urls.py,
我们先来给删除功能规划访问路径。
删除一定要知道删的是哪一条数据, 所以 URL 必须带主键 pk:
# 代码位置:grades/urls.py
from django.urls import path,include
from .views import GradeListView,GradeCreateView,GradeUpdateView,GradeDeleteView
urlpatterns = [
path('',GradeListView.as_view(),name='grades_list'),
path('create/', GradeCreateView.as_view(), name='grade_create'),
path('<int:pk>/update/', GradeUpdateView.as_view(), name='grade_update'),
# 新增
path('<int:pk>/delete/', GradeDeleteView.as_view(), name='grade_delete'),
]
这一行代码你只需要记住一件事:
没有 pk,就谈不上删除。
URL 写完以后, 你现在可以先停一下,确认一件事:
- 路径清晰
- 名字语义明确
很好,继续。
3.创建删除视图:DeleteView
接下来回到 grades/views.py。
这里我不再写函数视图, 而是继续用 Django 的通用类视图。
# 代码位置
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
class GradeListView(ListView):
pass
class GradeCreateView(CreateView):
pass
class GradeUpdateView(UpdateView):
pass
# 新增
class GradeDeleteView(DeleteView):
model = Grade
template_name = 'grades/grade_delete_confirm.html'
success_url = reverse_lazy('grades_list')
我们一行一行来看(别跳过,这里是理解关键):
DeleteView👉 Django 已经帮你封装好了删除逻辑model = Grade👉 告诉 Django:我要删的是哪个模型template_name👉 删除前,一定要展示一个确认页面success_url👉 删完以后,回到列表页
注意一件非常重要的事:
你没有写任何删除代码。
不是你偷懒,是 Django 已经帮你把这件事做对了。
4.创建删除确认模板
接下来我们去创建模板文件。
路径是:
templates/
└── grades/
└── grade_delete_confirm.html
如下图:

这个页面的作用只有一个:
让用户清楚地知道:他正在删除哪一个班级。
模板内容其实非常简单,代码如下:
# 代码位置:templates/grades/grade_delete_confirm.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<link rel="stylesheet" href="{% static 'css/form.css' %}">
<div class="bottom">
<div class="container">
<h1 style="text-align:center"> 确认删除? </h1>
<p style="margin: 20px;">你确定要删除【 {{ grade.grade_name }} 】 吗? 此操作不可撤销。"</p>
<form action="" method="post" class="text-align:center">
{% csrf_token %}
<div class="handleButton">
<button type="submit" id="cancelButton"> 确认删除 </button>
<a href="{% url 'grades_list' %}">
<button type="button">取消</button>
</a>
</div>
</form>
</div>
</div>
{% endblock %}
这里我重点强调三件事:
1️⃣ grade 是谁?
在 DeleteView 中:
- 当前要删除的对象
- 会自动传给模板
- 名字就叫
grade
所以你可以直接用:
{{ grade.grade_name }}
来显示班级名称。
2️⃣ 为什么一定要 CSRF Token?
因为这是一个 POST 请求。
删除操作是敏感操作, Django 默认会保护你。
你要做的只是配合它:
{% csrf_token %}
3️⃣ 表单提交到哪里?
你会发现:
<form method="post">
没有写 action。
这不是疏忽, 而是 Django 的惯用写法:
不写 action = 提交到当前视图。
而当前视图正是 GradeDeleteView,它会自动执行删除。
5.让「删除按钮」真正跳起来
现在回到班级列表页。
在原来「编辑」按钮旁边,我们加上「删除」按钮。
# 代码位置:templates/grades/grades_list.html
<td>
<a href="{% url 'grade_update' grade.id %}">
<button class="add">编辑</button>
</a>
<a href="{% url 'grade_delete' grade.id %}">
<button class="del">删除</button>
</a>
</td>
这里你只要记住一句话:
删除按钮本质上是“跳转到确认页”。
6.完整流程验证
现在我们来验证完整流程如下:
flowchart TB
A[班级列表页刷新]
A --> B[点击删除按钮]
B --> C[进入确认页面]
C --> D[显示待删除班级名称]
D --> E[确认删除]
E --> F[跳转回列表页]
F --> G[班级数据已不存在]
这一刻,你其实已经完成了:
一个完整、规范、安全的删除功能。


7.到这里,你已经完成了真正的 CRUD
我们停下来回顾一下。
到现在为止,你已经实现了:
- ListView:查询
- CreateView:新增
- UpdateView:编辑
- DeleteView:删除
而且你会发现一个非常舒服的事实:
四个功能,用的是同一套设计逻辑。
这就是 Django 通用类视图真正的价值。
本节小结
这一节,你不只是学会了「怎么删」。
你真正学会的是:
- 删除一定要有确认页
- DeleteView 的标准使用方式
- 如何在模板中获取当前对象
- 为什么 Django 值得你信任
你已经不是在「练习 CRUD」了,而是在按真实项目的方式写代码。
下一步你现在就该做的事(别跳)
我强烈建议你立刻做三件事:
- 故意点错删除,确认页面是否显示正确对象
- 删完后刷新页面,看数据是否真的消失
- 想一想: 👉 如果是“删除学生”,流程是不是一模一样?
下一章,我们就要做一件更接近真实系统的事了:
权限控制:谁能删?谁不能删?
到那一步,你的项目就真正「像一个系统」了。
好,这一节我们就讲到这里。 小伙伴们,下节再见 👋
【大熊课堂精品课程】
Python零基础入门动画课: https://www.bilibili.com/cheese/play/ss7988
Django+Vue:全栈开发: https://www.bilibili.com/cheese/play/ss8134
PyQT6开发桌面软件: https://www.bilibili.com/cheese/play/ss12314
Python办公自动化: https://www.bilibili.com/cheese/play/ss14990
Cursor AI编程+MCP:零基础实战项目课: https://www.bilibili.com/cheese/play/ss105194189
Pandas数据分析实战: https://www.bilibili.com/cheese/play/ss734522035
AI大模型+Python小白应用实战: https://www.bilibili.com/cheese/play/ss3844