4.使用 Django 通用视图实现前台班级管理

在上一章中,我们已经完成了一件非常关键的事情: 通过 Django 后台(Admin)实现了班级数据的增删改查。

这一步的意义在于:
- 验证了模型设计是正确的
- 数据可以被持久化到数据库
- Django 的 ORM 和后台系统已经正常工作
但这还远远不够。
为什么后台还不够?
在一个真实的教学管理系统中,我们的用户有不同的角色,比如管理员、老师和学生。例如:

每个角色又尤其对用的权限。例如:
- 学生只能查看自己的成绩信息
- 老师可以管理本班的学生信息,和成绩信息
- 管理员具备最高权限,可以管理班级、老师和学生等。
所以,这个后台我们只对管理员用户开放。而其他功能,而我们还需要:
- 面向学生或老师的前台页面
- 可访问的网址
- 清晰的业务入口
前台页面效果如下:

而这些功能,几乎都逃不开同一个核心问题:
如何高效地实现增删改查(CRUD)?
如果手写 CRUD,会发生什么?
你当然可以选择一种方式:
-
每个功能
-
每个页面
-
每个操作
全部手写视图函数,例如:
def grade_create_view(requets):
"""新增班级"""
pass
def grade_edit_view(requets):
"""编辑班级"""
pass
def grade_delete_view(requets):
"""删除班级"""
pass
def student_create_view(requets):
"""新增学生"""
pass
def student_edit_view(requets):
"""编辑学生"""
pass
......
但这样做会带来两个严重问题:
- 重复劳动极多
- 完全浪费 Django 已经提供的能力
Django 之所以被称为一个「大而全」的框架,正是因为它已经帮你把最常见的 Web 场景提前实现好了。
我们的目标,应该是:
把精力放在业务本身,而不是重复造轮子。
Django 的答案:通用类视图(Generic Views)
从这一节开始,我们将正式使用 Django 提供的 通用类视图(CBV) 来实现前台功能。
这一类视图,已经封装好了:
- 列表展示
- 新增数据
- 修改数据
- 删除数据
你只需要:
- 指定使用哪个模型
- 使用哪个模板
- Django 就会自动完成剩下的工作
这一节,我们先从班级列表页开始。
一、设计访问路径(URL)
我们希望用户能够通过下面的地址访问班级管理:
http://127.0.0.1:8000/grades/
将来还可以扩展为:
/grades/create/—— 新增班级/grades/update/—— 编辑班级/grades/delete/—— 删除班级
第一步,先让 /grades/ 能访问到一个页面。
二、配置全局路由(urls.py)
在项目的全局配置文件 config/urls.py 中,我们添加一条路由:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('grades/',include('grades.urls')), # 新增班级路由
]
这里使用了 include,目的是:
- 将班级相关的 URL 单独拆分
- 保证项目结构清晰、可维护
这也是 Django 推荐的做法。
三、为 grades 应用创建路由文件
默认情况下,应用中并不会自动生成 urls.py,
因此我们需要在 grades 目录下手动创建:
grades/
├── urls.py
在这个文件中,定义班级列表的访问规则:
from django.urls import path
from .views import GradeListView
urlpatterns = [
path('', GradeListView.as_view(), name='grades_list'),
]
当用户访问 /grades/ 时,就会进入 GradeListView。
四、使用 ListView 创建班级列表视图
接下来,来到 grades/views.py。
我们不再编写传统的视图函数,而是使用 Django 提供的 ListView:
from django.shortcuts import render
from django.views.generic import ListView
from .models import Grade
# Create your views here.
class GradeListView(ListView):
model = Grade
template_name = 'grades/grades_list.html'
fieslds = ['grade_name','grade_number']
context_object_name = 'grades'
这里发生了三件非常重要的事情:
- model 指定要查询的数据模型(Grade)
- template_name 指定页面使用的模板
- context_object_name 指定传递到模板中的变量名
注意一个细节: 我们没有写任何查询数据库的代码。
这正是通用视图的强大之处。
五、理解 ListView 的继承关系
当我第一次使用视图类时,也是一头雾水。之前一直用函数视图,所有逻辑都写在函数里面。但是现在呢?一行代码都没写,它居然可以正常显示班级数据了。这是为什么呢?
如果你点进 ListView 的源码,会发现它:
- 最终继承自
View - 内部已经实现了完整的查询逻辑
- 自动调用 ORM 获取数据
- 自动传递给模板
也就是说:
你只是在“配置”,而不是在“编程”。
再次感叹Django代码的强大😁
六、创建模板文件
接下来创建模板目录结构:
templates/
└── grades/
└── grades_list.html
先写一个最简单的内容,验证是否能访问成功:
<h1>班级列表</h1>
启动开发服务器,访问:
http://127.0.0.1:8000/grades/

如果页面能够正常显示,说明:
- 路由配置正确
- 视图类生效
- 模板加载成功
七、在模板中展示班级数据
现在,我们希望把数据库中的班级数据展示出来。如果你还没有数据,可以在后台添加,添加完成后如下所示:

在模板中使用 Django 模板语言进行遍历。在Django模版中,遍历数据使用{% for %} 和 {% endfor %}标签。它和python的语法非常类似。{% for grade in grades %} 表示将grades依次赋值给grade对象。 grades_list.html代码如下:
<h1>班级列表</h1>
`{% for grade in grades %}`
<div>
{{ grade.grade_name }} - {{ grade.grade_number }}
</div>
`{% endfor %}`
这里的 grades,正是我们在视图类中设置的 context_object_name。
八、验证效果
当你在后台新增多个班级后,再刷新页面:
- 页面会自动显示所有班级
- 不需要修改任何视图代码
- 不需要手写 SQL
如下图:

至此,我们已经完成了:
零业务代码,实现班级列表功能。
本章小结
在这一章中,你学到了:
- 为什么后台不能替代前台
- 如何拆分应用级 URL
- Django 通用类视图的核心思想
- 使用
ListView快速实现列表页
你也应该逐渐体会到 Django 的设计哲学:
能配置的,绝不让你手写。
在下一章中,我们将继续完善这个页面:
- 引入模板布局
- 美化页面结构
- 为后续的新增、修改、删除做好准备
这才是真正的 Web 应用开发流程。下节见!
【大熊课堂精品课程】
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