Skip to main content

8.班级管理的最后一块拼图:删除功能

到目前为止,其实你已经完成了一件非常不容易的事情

  • 班级能查
  • 班级能加
  • 班级能改

现在,就只剩下最后一个功能了。

也是很多新手最不敢点的那个按钮—— 👉 删除班级

在正式写代码之前,可能你心里一定会冒出一个问题:

“万一一点就没了怎么办?”

所以,删除功能的第一原则只有一句话:

永远不要直接删,一定要先确认。

这一节,我们要做的,就是一个标准、专业、可控的删除流程

1.删除功能的整体思路

在动手之前,我们先想清楚用户的操作路径:

  1. 在班级列表页点击「删除」
  2. 跳转到一个 确认页面
  3. 用户明确点击「确认删除」
  4. 才真正执行删除
  5. 删除完成后,回到列表页

只要你把这 5 步想清楚,后面的代码就一点都不难

image-20260104175710142

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

如下图: image-20260104175905296

这个页面的作用只有一个:

让用户清楚地知道:他正在删除哪一个班级。

模板内容其实非常简单,代码如下:

# 代码位置: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[班级数据已不存在]

这一刻,你其实已经完成了:

一个完整、规范、安全的删除功能。

image-20260104175710142

image-20260104175740399

7.到这里,你已经完成了真正的 CRUD

我们停下来回顾一下。

到现在为止,你已经实现了:

  • ListView:查询
  • CreateView:新增
  • UpdateView:编辑
  • DeleteView:删除

而且你会发现一个非常舒服的事实:

四个功能,用的是同一套设计逻辑。

这就是 Django 通用类视图真正的价值。

本节小结

这一节,你不只是学会了「怎么删」。

你真正学会的是:

  • 删除一定要有确认页
  • DeleteView 的标准使用方式
  • 如何在模板中获取当前对象
  • 为什么 Django 值得你信任

你已经不是在「练习 CRUD」了,而是在按真实项目的方式写代码

下一步你现在就该做的事(别跳)

我强烈建议你立刻做三件事:

  1. 故意点错删除,确认页面是否显示正确对象
  2. 删完后刷新页面,看数据是否真的消失
  3. 想一想: 👉 如果是“删除学生”,流程是不是一模一样?

下一章,我们就要做一件更接近真实系统的事了:

权限控制:谁能删?谁不能删?

到那一步,你的项目就真正「像一个系统」了。

好,这一节我们就讲到这里。 小伙伴们,下节再见 👋