Python 从入门到实战(十二):Flask Web 开发(把学生成绩系统变成在线应用)

文章目录
- 一、为什么选择 Flask?Web 开发的 “入门钥匙”
- 二、Flask 基础:从 “Hello World” 到 Web 服务
- 三、Flask 进阶:整合学生数据与 Web 页面
- 四、Flask + 可视化:Web 页面展示图表
- 五、交互功能:学生成绩查询
- 六、完整项目实战:在线学生成绩管理系统
- 七、新手必踩的 5 个坑:避坑指南
- 坑 1:模板路径错误(找不到 HTML 文件)
- 坑 2:静态文件引用错误(图表不显示)
- 坑 3:请求方法错误(表单提交没反应)
- 坑 4:数据读取路径错误(找不到 CSV 文件)
- 坑 5:调试模式关闭(修改代码不生效)
- 八、小结与下一篇预告
欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们用 Matplotlib 和 Seaborn 实现了学生成绩的可视化,生成了美观的图表报告,但这些功能都局限在本地 —— 只有在自己的电脑上才能运行,老师和学生无法通过浏览器远程访问。
今天咱们要学 Python 的轻量级 Web 框架 ——Flask。它就像一座 “桥梁”,能把咱们之前写的本地学生成绩管理、数据可视化逻辑,快速升级为在线 Web 应用,让多人通过浏览器访问、查询成绩、查看可视化报告。咱们会从 Flask 基础入手,逐步实现 “首页展示→学生列表→成绩查询→可视化报告” 的完整功能,最终打造一个能实际使用的 “在线学生成绩管理系统”。
一、为什么选择 Flask?Web 开发的 “入门钥匙”
在学具体操作前,先搞懂 “为什么要做 Web 应用” 和 “为什么选 Flask”:
- 本地项目的局限:之前的学生系统只能在自己电脑上运行,无法共享;数据和图表都存在本地文件,多人协作不方便;
- Web 应用的优势:只要有浏览器(电脑、手机都可以),就能访问系统;数据集中存储,多人实时查看最新成绩;
- Flask 的特点:轻量级、易上手,不需要复杂配置,适合快速把本地项目升级为 Web 应用;支持整合 Pandas、Matplotlib 等库,完美衔接咱们之前的代码。
简单说:Flask 能以最低的学习成本,让你的本地工具变成 “人人可用的在线服务”。
二、Flask 基础:从 “Hello World” 到 Web 服务
首先,咱们先搞定 Flask 的安装和核心概念,用 3 行代码跑通第一个 Web 服务,建立基础认知。
1. 安装 Flask 与依赖
Flask 是第三方库,需要先安装。另外,咱们还要用到 Pandas(处理数据)、Matplotlib(生成图表),所以一起安装:
bash
# 安装Flask核心库
pip install flask
# 安装依赖(数据处理和可视化)
pip install pandas matplotlib seaborn
安装完成后,验证是否成功:打开 Python 终端,输入import flask,没有报错就说明安装成功。
2. 核心概念:Flask 的 “三大件”
Flask 有三个核心概念,搞懂它们就能入门 Web 开发:
- 路由(Route):URL 地址与 Python 函数的映射关系。比如访问
http://localhost:5000/(首页),对应执行index()函数; - 视图函数(View Function):处理路由请求的 Python 函数,负责逻辑计算(比如读取数据、生成图表),并返回响应(比如 HTML 页面、字符串);
- 模板(Template):用于渲染 Web 页面的 HTML 文件,通过 Jinja2 模板引擎,能把 Python 变量(比如学生数据)动态插入到 HTML 中,让页面 “活” 起来。
3. 实战 1:跑通第一个 Flask 应用(Hello World)
创建一个名为app.py的文件(Flask 项目的主程序文件),写入以下代码:
python
# app.py(Flask主程序)
from flask import Flask
# 1. 初始化Flask应用(__name__表示当前文件作为应用入口)
app = Flask(__name__)
# 2. 定义路由:访问根URL(http://localhost:5000/)时,执行index()函数
@app.route('/')
def index():
# 3. 视图函数:返回响应内容(这里是简单的字符串)
return "<h1>欢迎访问学生成绩管理系统!</h1><p>这是用Flask开发的Web应用</p>"
# 4. 启动Web服务(只有直接运行app.py时才执行)
if __name__ == '__main__':
# debug=True:开启调试模式,修改代码后自动重启服务,方便开发
app.run(debug=True)
运行步骤:
-
打开终端,进入
app.py所在的文件夹; -
执行命令
python app.py,看到以下输出:plaintext
* Serving Flask app 'app' * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) -
打开浏览器,访问
http://localhost:5000/,就能看到页面显示:- 大标题 “欢迎访问学生成绩管理系统!”
- 副标题 “这是用 Flask 开发的 Web 应用”
关键说明:
- 调试模式:
debug=True非常重要,开发时开启,修改代码后不用手动重启服务; - URL 与路由:
@app.route('/')对应根 URL,如果你定义@app.route('/student'),访问http://localhost:5000/student才会触发对应的视图函数; - 响应内容:目前返回的是简单 HTML 字符串,后面会用模板返回更复杂的页面。
三、Flask 进阶:整合学生数据与 Web 页面
单纯的字符串响应不够美观,也无法展示复杂的学生数据。接下来,咱们用模板渲染 HTML 页面,把之前的学生 CSV 数据展示成 Web 表格,实现 “本地数据→Web 表格” 的跨越。
1. 项目结构:规范文件组织
随着功能增加,文件需要按规则存放,否则会混乱。创建以下项目结构(跟着手动建文件夹和文件):
plaintext
student_web/ # 项目根文件夹
├── app.py # 主程序文件(Flask核心逻辑)
├── students_data.csv # 学生数据文件(之前生成的)
├── templates/ # 存放HTML模板的文件夹
│ ├── base.html # 基础模板(所有页面继承这个)
│ ├── index.html # 首页
│ └── student_list.html # 学生列表页
└── static/ # 存放静态文件(图片、CSS、JS)
└── images/ # 存放可视化图表的文件夹
2. 模板继承:减少重复 HTML 代码
Web 开发中,多个页面(如首页、学生列表页)会有相同的头部(导航栏)和底部(版权信息),用模板继承可以避免重复写这些代码。
步骤 1:创建基础模板templates/base.html
html
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}学生成绩管理系统{% endblock %}</title>
<!-- 引入简单的CSS,让页面更美观(Bootstrap,不用自己写CSS) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!-- 导航栏(所有页面都有) -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">学生成绩系统</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/student/list">学生列表</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/report">可视化报告</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- 内容区域(子页面在这里填充不同内容) -->
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<!-- 底部信息(所有页面都有) -->
<footer class="mt-5 py-3 bg-light text-center">
<div class="container">
<p class="mb-0">© 2024 学生成绩管理系统 | 用Flask开发</p>
</div>
</footer>
<!-- Bootstrap的JS(可选,用于交互) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
模板继承说明:
{% block title %}:子页面可以替换这里的标题;{% block content %}:子页面的核心内容放在这里;- 引入 Bootstrap:这是一个免费的 CSS/JS 库,不用自己写样式就能让页面美观,新手友好。
3. 首页开发:templates/index.html
首页继承base.html,展示系统简介和快速入口:
html
<!-- templates/index.html -->
{% extends "base.html" %}
<!-- 替换标题 -->
{% block title %}首页 - 学生成绩管理系统{% endblock %}
<!-- 填充内容区域 -->
{% block content %}
<div class="jumbotron bg-light p-5 rounded-3">
<h1 class="display-5 fw-bold">欢迎使用学生成绩管理系统</h1>
<p class="lead mt-3">本系统基于Python Flask开发,整合Pandas数据处理和Matplotlib可视化,支持以下功能:</p>
<ul class="list-group list-group-flush mt-3 w-50">
<li class="list-group-item">查看所有学生的成绩列表</li>
<li class="list-group-item">查询单个学生的详细成绩</li>
<li class="list-group-item">查看各科成绩的可视化报告</li>
</ul>
<div class="mt-4">
<a href="/student/list" class="btn btn-primary me-3">进入学生列表</a>
<a href="/report" class="btn btn-success">查看可视化报告</a>
</div>
</div>
{% endblock %}
4. 学生列表页:展示 Pandas 处理的数据
接下来,在app.py中添加路由和视图函数,用 Pandas 读取students_data.csv,传递到模板,渲染成 Web 表格。
步骤 1:修改app.py,添加学生列表路由
python
# app.py(新增代码,放在index路由后面)
import pandas as pd
from flask import Flask, render_template # 新增render_template,用于渲染模板
app = Flask(__name__)
# 首页路由(之前的代码)
@app.route('/')
def index():
# 渲染index.html模板,不再返回字符串
return render_template('index.html')
# 新增:学生列表路由
@app.route('/student/list')
def student_list():
# 1. 用Pandas读取学生数据(和之前本地处理一样)
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
# 添加成绩等级列(复用之前的逻辑)
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 2. 将DataFrame转换为字典列表,方便模板渲染(Flask不支持直接传递DataFrame)
student_data = df.to_dict('records') # 每一行是一个字典,键是列名
# 3. 计算统计信息(传递到模板展示)
total_students = df['name'].nunique() # 总学生数
total_courses = df['course_name'].nunique() # 总课程数
# 4. 渲染student_list.html,传递数据到模板
return render_template(
'student_list.html',
students=student_data, # 学生数据列表
total_students=total_students, # 总学生数
total_courses=total_courses # 总课程数
)
# 启动服务(之前的代码)
if __name__ == '__main__':
app.run(debug=True)
步骤 2:创建学生列表模板templates/student_list.html
html
<!-- templates/student_list.html -->
{% extends "base.html" %}
{% block title %}学生列表 - 学生成绩管理系统{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>学生成绩列表</h2>
<p class="text-muted">总学生数:{{ total_students }} 人 | 总课程数:{{ total_courses }} 门</p>
</div>
<!-- 学生成绩表格 -->
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr>
<th>学生姓名</th>
<th>年龄</th>
<th>课程名称</th>
<th>成绩(分)</th>
<th>成绩等级</th>
</tr>
</thead>
<tbody>
<!-- 循环渲染学生数据 -->
{% for student in students %}
<tr>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.course_name }}</td>
<td>{{ student.course_score }}</td>
<td>
<!-- 根据等级显示不同颜色 -->
{% if student.grade == 'A级(90+)' %}
<span class="badge bg-success">{{ student.grade }}</span>
{% elif student.grade == 'B级(80-89)' %}
<span class="badge bg-warning">{{ student.grade }}</span>
{% else %}
<span class="badge bg-danger">{{ student.grade }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
运行测试:
- 确保
students_data.csv在项目根目录; - 运行
app.py,访问http://localhost:5000/student/list,就能看到:- 顶部显示总学生数和课程数;
- 美观的表格,展示每个学生的姓名、年龄、课程、成绩;
- 成绩等级用不同颜色的标签显示(A 级绿色、B 级黄色、C 级红色)。
四、Flask + 可视化:Web 页面展示图表
上一篇咱们生成了柱状图、饼图,但只能存在本地文件。现在要让这些图表在 Web 页面展示,步骤是:
- 在 Flask 中生成图表,保存到
static/images/文件夹; - 在模板中引用静态文件夹的图片路径,渲染到页面。
1. 修改app.py,添加可视化报告路由
python
# app.py(新增代码,放在student_list路由后面)
import matplotlib.pyplot as plt
import seaborn as sns
import os
# 配置中文字体(避免图表中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
sns.set_style("whitegrid")
# 确保static/images文件夹存在(不存在则创建)
if not os.path.exists('static/images'):
os.makedirs('static/images')
# 新增:可视化报告路由
@app.route('/report')
def report():
# 1. 读取数据(复用之前的逻辑)
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 2. 生成各科平均分柱状图
course_avg = df.groupby('course_name')['course_score'].mean().round(1)
fig, ax = plt.subplots(figsize=(6, 4), dpi=100)
bars = ax.bar(course_avg.index, course_avg.values, color='skyblue', edgecolor='black')
ax.set_title('各科平均分对比', fontsize=12)
ax.set_xlabel('课程名称')
ax.set_ylabel('平均分(分)')
ax.set_ylim(80, 90)
# 添加数值标签
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x()+bar.get_width()/2, height+0.5, str(height), ha='center', va='bottom')
# 保存图表到static/images
plt.savefig('static/images/course_avg.png', bbox_inches='tight')
plt.close() # 关闭图表,释放内存
# 3. 生成成绩等级分布饼图
grade_count = df['grade'].value_counts()
fig, ax = plt.subplots(figsize=(6, 6), dpi=100)
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
wedges, texts, autotexts = ax.pie(
grade_count.values, labels=grade_count.index, autopct='%1.1f%%',
startangle=90, colors=colors, explode=(0.05, 0, 0)
)
ax.set_title('成绩等级分布', fontsize=12)
for autotext in autotexts:
autotext.set_color('white')
plt.savefig('static/images/grade_pie.png', bbox_inches='tight')
plt.close()
# 4. 渲染报告模板,传递图表路径
return render_template('report.html')
2. 创建可视化报告模板templates/report.html
html
<!-- templates/report.html -->
{% extends "base.html" %}
{% block title %}可视化报告 - 学生成绩管理系统{% endblock %}
{% block content %}
<h2>学生成绩可视化报告</h2>
<p class="text-muted mb-4">基于学生成绩数据生成的图表分析</p>
<!-- 图表展示(2行1列,响应式布局) -->
<div class="row g-4">
<!-- 柱状图:各科平均分 -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">各科平均分对比</h5>
<!-- 引用静态文件夹的图片:url_for('static', filename='图片路径') -->
<img src="{{ url_for('static', filename='images/course_avg.png') }}"
alt="各科平均分柱状图" class="img-fluid">
</div>
</div>
</div>
<!-- 饼图:成绩等级分布 -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">成绩等级分布</h5>
<img src="{{ url_for('static', filename='images/grade_pie.png') }}"
alt="成绩等级饼图" class="img-fluid">
</div>
</div>
</div>
</div>
{% endblock %}
关键说明:
url_for('static', filename='images/course_avg.png'):Flask 的辅助函数,自动生成静态文件的 URL,避免手动写路径出错;img-fluid:Bootstrap 的类,让图片自适应页面宽度,在手机上也能正常显示;card shadow-sm:给图表加卡片样式和阴影,让页面更有层次感。
运行测试:
访问http://localhost:5000/report,就能看到两个图表在 Web 页面上展示,和之前本地生成的一样,但现在任何人都能通过浏览器访问。
五、交互功能:学生成绩查询
只展示还不够,还要支持 “用户输入姓名,查询该学生的成绩”。这需要用到 Flask 的表单处理,接收用户输入的姓名,查询数据后返回结果。
1. 修改app.py,添加查询路由
python
# app.py(新增代码,放在report路由后面)
from flask import request # 新增request对象,用于接收请求数据
# 新增:学生查询路由(支持GET和POST请求)
@app.route('/student/search', methods=['GET', 'POST'])
def student_search():
# 如果是GET请求(用户刚访问页面),返回空结果的表单
if request.method == 'GET':
return render_template('student_search.html')
# 如果是POST请求(用户提交表单),处理查询
elif request.method == 'POST':
# 1. 获取用户输入的姓名(从表单中取name为'student_name'的值)
student_name = request.form.get('student_name', '').strip()
# 2. 验证输入(不能为空)
if not student_name:
return render_template('student_search.html', error='请输入学生姓名!')
# 3. 读取数据并查询
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 筛选该学生的数据
student_df = df[df['name'] == student_name]
# 4. 处理查询结果
if student_df.empty:
# 没有找到该学生
return render_template(
'student_search.html',
error=f'未找到名为“{student_name}”的学生',
input_name=student_name # 回显用户输入的姓名
)
else:
# 找到学生,转换为字典列表
student_data = student_df.to_dict('records')
# 计算该学生的总分和平均分
total_score = student_df['course_score'].sum()
avg_score = student_df['course_score'].mean().round(1)
return render_template(
'student_search.html',
student=student_data, # 学生成绩数据
total_score=total_score, # 总分
avg_score=avg_score, # 平均分
input_name=student_name # 回显用户输入的姓名
)
2. 创建查询模板templates/student_search.html
html
<!-- templates/student_search.html -->
{% extends "base.html" %}
{% block title %}学生查询 - 学生成绩管理系统{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<h2>学生成绩查询</h2>
<!-- 成绩查询表单 -->
<form method="POST" class="mt-4">
<div class="input-group mb-3">
<input type="text" name="student_name" class="form-control"
placeholder="请输入学生姓名(如:小明)"
value="{{ input_name if input_name else '' }}"> <!-- 回显输入 -->
<button class="btn btn-primary" type="submit">查询</button>
</div>
<!-- 显示错误信息(如果有) -->
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
</form>
<!-- 显示查询结果(如果有) -->
{% if student %}
<div class="card mt-4">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">
{{ input_name }} 的成绩详情
<span class="float-end">总分:{{ total_score }} | 平均分:{{ avg_score }}</span>
</h5>
</div>
<div class="card-body">
<table class="table table-sm mb-0">
<thead>
<tr>
<th>课程名称</th>
<th>成绩(分)</th>
<th>成绩等级</th>
</tr>
</thead>
<tbody>
{% for item in student %}
<tr>
<td>{{ item.course_name }}</td>
<td>{{ item.course_score }}</td>
<td>
{% if item.grade == 'A级(90+)' %}
<span class="badge bg-success">{{ item.grade }}</span>
{% elif item.grade == 'B级(80-89)' %}
<span class="badge bg-warning">{{ item.grade }}</span>
{% else %}
<span class="badge bg-danger">{{ item.grade }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
关键功能说明:
- 请求方法:
methods=['GET', 'POST']表示该路由支持两种请求:GET(访问页面)、POST(提交表单); - 表单回显:
value="{{ input_name if input_name else '' }}"让用户查询失败时,输入框保留之前的内容,不用重新输入; - 错误提示:用 Bootstrap 的
alert-danger类显示错误信息(如 “未找到学生”),用户体验更好。
运行测试:
- 访问
http://localhost:5000/student/search; - 输入 “小明”,点击查询,会显示小明的课程、成绩、总分和平均分;
- 输入 “不存在的名字”,会显示错误提示 “未找到该学生”。
六、完整项目实战:在线学生成绩管理系统
现在,咱们的系统已经有了 4 个核心功能:首页、学生列表、可视化报告、成绩查询。最后,把导航栏和所有功能串联起来,确保用户能通过导航在各个页面间切换(之前的base.html已经做好了导航栏)。
最终项目结构回顾
plaintext
student_web/
├── app.py # 主程序(路由、数据处理、图表生成)
├── students_data.csv # 学生数据(数据源)
├── templates/
│ ├── base.html # 基础模板(导航栏、底部)
│ ├── index.html # 首页(系统简介)
│ ├── student_list.html # 学生列表(所有成绩表格)
│ ├── student_search.html # 成绩查询(交互功能)
│ └── report.html # 可视化报告(图表展示)
└── static/
└── images/
├── course_avg.png # 柱状图(自动生成)
└── grade_pie.png # 饼图(自动生成)
运行完整系统的步骤
- 确保所有文件按上述结构存放;
- 安装所有依赖(flask、pandas、matplotlib、seaborn);
- 运行
python app.py,打开浏览器访问http://localhost:5000/; - 通过导航栏切换 “首页→学生列表→成绩查询→可视化报告”,测试所有功能。
七、新手必踩的 5 个坑:避坑指南
Flask 开发虽然简单,但新手容易在 “路径”“请求处理”“静态文件” 上踩坑,总结如下:
坑 1:模板路径错误(找不到 HTML 文件)
python
# 错误示例:模板不在templates文件夹,或文件名写错
return render_template('studentlist.html') # 错误:正确文件名是student_list.html
解决:
- 模板必须放在
templates文件夹(名字不能错,全小写); - 渲染时文件名必须和实际一致,包括下划线、大小写(Flask 区分大小写)。
坑 2:静态文件引用错误(图表不显示)
html
<!-- 错误示例:直接写本地路径,Flask无法识别 -->
<img src="static/images/course_avg.png">
解决:用url_for生成静态文件 URL:
html
<img src="{{ url_for('static', filename='images/course_avg.png') }}">
坑 3:请求方法错误(表单提交没反应)
python
# 错误示例:路由只支持GET,无法处理POST请求
@app.route('/student/search') # 默认methods=['GET']
def student_search():
if request.method == 'POST': # 永远不会执行
pass
解决:路由必须显式指定支持 POST:
python
@app.route('/student/search', methods=['GET', 'POST'])
坑 4:数据读取路径错误(找不到 CSV 文件)
python
# 错误示例:CSV文件不在项目根目录,Pandas找不到
df = pd.read_csv('data/students_data.csv') # 错误:路径不对
解决:
-
确保
students_data.csv在app.py所在的根目录; -
或用绝对路径(不推荐,换电脑会失效):
python
import os csv_path = os.path.join(os.path.dirname(__file__), 'students_data.csv') df = pd.read_csv(csv_path)
坑 5:调试模式关闭(修改代码不生效)
python
# 错误示例:debug=False,修改代码后需要手动重启服务
app.run(debug=False)
解决:开发时务必开启调试模式:
python
app.run(debug=True)
注意:生产环境(给别人正式使用时)要关闭debug=True,否则有安全风险。
八、小结与下一篇预告
这篇你学到了什么?
- Flask 基础:理解路由、视图函数、模板的核心概念,跑通 Web 服务;
- 模板开发:用 Jinja2 模板继承减少重复代码,引入 Bootstrap 美化页面;
- 数据整合:把 Pandas 本地数据处理逻辑迁移到 Flask,渲染成 Web 表格;
- 可视化 Web 化:在 Flask 中生成图表,保存到静态文件夹,在页面展示;
- 交互功能:用 request 处理表单提交,实现学生成绩查询,提升用户体验;
- 项目实战:构建完整的在线学生成绩管理系统,掌握 Web 项目的文件结构和开发流程。
下一篇预告
今天的 Flask 应用已经能通过浏览器访问,但数据还是存在本地 CSV 文件中,多人同时修改会冲突,而且无法持久化存储新数据(比如新增学生)。下一篇咱们会学 Python 的数据库操作,用SQLite(轻量级数据库,无需安装)替换 CSV 文件,实现数据的增删改查,让 Web 应用真正支持多人协作,成为生产级别的系统。
如果这篇内容帮你搭建了第一个 Flask 应用,欢迎在评论区分享你的系统截图或遇到的问题,咱们一起交流进步~

文章目录
- 一、为什么选择 Flask?Web 开发的 “入门钥匙”
- 二、Flask 基础:从 “Hello World” 到 Web 服务
- 三、Flask 进阶:整合学生数据与 Web 页面
- 四、Flask + 可视化:Web 页面展示图表
- 五、交互功能:学生成绩查询
- 六、完整项目实战:在线学生成绩管理系统
- 七、新手必踩的 5 个坑:避坑指南
- 坑 1:模板路径错误(找不到 HTML 文件)
- 坑 2:静态文件引用错误(图表不显示)
- 坑 3:请求方法错误(表单提交没反应)
- 坑 4:数据读取路径错误(找不到 CSV 文件)
- 坑 5:调试模式关闭(修改代码不生效)
- 八、小结与下一篇预告
欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们用 Matplotlib 和 Seaborn 实现了学生成绩的可视化,生成了美观的图表报告,但这些功能都局限在本地 —— 只有在自己的电脑上才能运行,老师和学生无法通过浏览器远程访问。
今天咱们要学 Python 的轻量级 Web 框架 ——Flask。它就像一座 “桥梁”,能把咱们之前写的本地学生成绩管理、数据可视化逻辑,快速升级为在线 Web 应用,让多人通过浏览器访问、查询成绩、查看可视化报告。咱们会从 Flask 基础入手,逐步实现 “首页展示→学生列表→成绩查询→可视化报告” 的完整功能,最终打造一个能实际使用的 “在线学生成绩管理系统”。
一、为什么选择 Flask?Web 开发的 “入门钥匙”
在学具体操作前,先搞懂 “为什么要做 Web 应用” 和 “为什么选 Flask”:
- 本地项目的局限:之前的学生系统只能在自己电脑上运行,无法共享;数据和图表都存在本地文件,多人协作不方便;
- Web 应用的优势:只要有浏览器(电脑、手机都可以),就能访问系统;数据集中存储,多人实时查看最新成绩;
- Flask 的特点:轻量级、易上手,不需要复杂配置,适合快速把本地项目升级为 Web 应用;支持整合 Pandas、Matplotlib 等库,完美衔接咱们之前的代码。
简单说:Flask 能以最低的学习成本,让你的本地工具变成 “人人可用的在线服务”。
二、Flask 基础:从 “Hello World” 到 Web 服务
首先,咱们先搞定 Flask 的安装和核心概念,用 3 行代码跑通第一个 Web 服务,建立基础认知。
1. 安装 Flask 与依赖
Flask 是第三方库,需要先安装。另外,咱们还要用到 Pandas(处理数据)、Matplotlib(生成图表),所以一起安装:
bash
# 安装Flask核心库
pip install flask
# 安装依赖(数据处理和可视化)
pip install pandas matplotlib seaborn
安装完成后,验证是否成功:打开 Python 终端,输入import flask,没有报错就说明安装成功。
2. 核心概念:Flask 的 “三大件”
Flask 有三个核心概念,搞懂它们就能入门 Web 开发:
- 路由(Route):URL 地址与 Python 函数的映射关系。比如访问
http://localhost:5000/(首页),对应执行index()函数; - 视图函数(View Function):处理路由请求的 Python 函数,负责逻辑计算(比如读取数据、生成图表),并返回响应(比如 HTML 页面、字符串);
- 模板(Template):用于渲染 Web 页面的 HTML 文件,通过 Jinja2 模板引擎,能把 Python 变量(比如学生数据)动态插入到 HTML 中,让页面 “活” 起来。
3. 实战 1:跑通第一个 Flask 应用(Hello World)
创建一个名为app.py的文件(Flask 项目的主程序文件),写入以下代码:
python
# app.py(Flask主程序)
from flask import Flask
# 1. 初始化Flask应用(__name__表示当前文件作为应用入口)
app = Flask(__name__)
# 2. 定义路由:访问根URL(http://localhost:5000/)时,执行index()函数
@app.route('/')
def index():
# 3. 视图函数:返回响应内容(这里是简单的字符串)
return "<h1>欢迎访问学生成绩管理系统!</h1><p>这是用Flask开发的Web应用</p>"
# 4. 启动Web服务(只有直接运行app.py时才执行)
if __name__ == '__main__':
# debug=True:开启调试模式,修改代码后自动重启服务,方便开发
app.run(debug=True)
运行步骤:
-
打开终端,进入
app.py所在的文件夹; -
执行命令
python app.py,看到以下输出:plaintext
* Serving Flask app 'app' * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) -
打开浏览器,访问
http://localhost:5000/,就能看到页面显示:- 大标题 “欢迎访问学生成绩管理系统!”
- 副标题 “这是用 Flask 开发的 Web 应用”
关键说明:
- 调试模式:
debug=True非常重要,开发时开启,修改代码后不用手动重启服务; - URL 与路由:
@app.route('/')对应根 URL,如果你定义@app.route('/student'),访问http://localhost:5000/student才会触发对应的视图函数; - 响应内容:目前返回的是简单 HTML 字符串,后面会用模板返回更复杂的页面。
三、Flask 进阶:整合学生数据与 Web 页面
单纯的字符串响应不够美观,也无法展示复杂的学生数据。接下来,咱们用模板渲染 HTML 页面,把之前的学生 CSV 数据展示成 Web 表格,实现 “本地数据→Web 表格” 的跨越。
1. 项目结构:规范文件组织
随着功能增加,文件需要按规则存放,否则会混乱。创建以下项目结构(跟着手动建文件夹和文件):
plaintext
student_web/ # 项目根文件夹
├── app.py # 主程序文件(Flask核心逻辑)
├── students_data.csv # 学生数据文件(之前生成的)
├── templates/ # 存放HTML模板的文件夹
│ ├── base.html # 基础模板(所有页面继承这个)
│ ├── index.html # 首页
│ └── student_list.html # 学生列表页
└── static/ # 存放静态文件(图片、CSS、JS)
└── images/ # 存放可视化图表的文件夹
2. 模板继承:减少重复 HTML 代码
Web 开发中,多个页面(如首页、学生列表页)会有相同的头部(导航栏)和底部(版权信息),用模板继承可以避免重复写这些代码。
步骤 1:创建基础模板templates/base.html
html
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}学生成绩管理系统{% endblock %}</title>
<!-- 引入简单的CSS,让页面更美观(Bootstrap,不用自己写CSS) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!-- 导航栏(所有页面都有) -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">学生成绩系统</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/student/list">学生列表</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/report">可视化报告</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- 内容区域(子页面在这里填充不同内容) -->
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<!-- 底部信息(所有页面都有) -->
<footer class="mt-5 py-3 bg-light text-center">
<div class="container">
<p class="mb-0">© 2024 学生成绩管理系统 | 用Flask开发</p>
</div>
</footer>
<!-- Bootstrap的JS(可选,用于交互) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
模板继承说明:
{% block title %}:子页面可以替换这里的标题;{% block content %}:子页面的核心内容放在这里;- 引入 Bootstrap:这是一个免费的 CSS/JS 库,不用自己写样式就能让页面美观,新手友好。
3. 首页开发:templates/index.html
首页继承base.html,展示系统简介和快速入口:
html
<!-- templates/index.html -->
{% extends "base.html" %}
<!-- 替换标题 -->
{% block title %}首页 - 学生成绩管理系统{% endblock %}
<!-- 填充内容区域 -->
{% block content %}
<div class="jumbotron bg-light p-5 rounded-3">
<h1 class="display-5 fw-bold">欢迎使用学生成绩管理系统</h1>
<p class="lead mt-3">本系统基于Python Flask开发,整合Pandas数据处理和Matplotlib可视化,支持以下功能:</p>
<ul class="list-group list-group-flush mt-3 w-50">
<li class="list-group-item">查看所有学生的成绩列表</li>
<li class="list-group-item">查询单个学生的详细成绩</li>
<li class="list-group-item">查看各科成绩的可视化报告</li>
</ul>
<div class="mt-4">
<a href="/student/list" class="btn btn-primary me-3">进入学生列表</a>
<a href="/report" class="btn btn-success">查看可视化报告</a>
</div>
</div>
{% endblock %}
4. 学生列表页:展示 Pandas 处理的数据
接下来,在app.py中添加路由和视图函数,用 Pandas 读取students_data.csv,传递到模板,渲染成 Web 表格。
步骤 1:修改app.py,添加学生列表路由
python
# app.py(新增代码,放在index路由后面)
import pandas as pd
from flask import Flask, render_template # 新增render_template,用于渲染模板
app = Flask(__name__)
# 首页路由(之前的代码)
@app.route('/')
def index():
# 渲染index.html模板,不再返回字符串
return render_template('index.html')
# 新增:学生列表路由
@app.route('/student/list')
def student_list():
# 1. 用Pandas读取学生数据(和之前本地处理一样)
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
# 添加成绩等级列(复用之前的逻辑)
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 2. 将DataFrame转换为字典列表,方便模板渲染(Flask不支持直接传递DataFrame)
student_data = df.to_dict('records') # 每一行是一个字典,键是列名
# 3. 计算统计信息(传递到模板展示)
total_students = df['name'].nunique() # 总学生数
total_courses = df['course_name'].nunique() # 总课程数
# 4. 渲染student_list.html,传递数据到模板
return render_template(
'student_list.html',
students=student_data, # 学生数据列表
total_students=total_students, # 总学生数
total_courses=total_courses # 总课程数
)
# 启动服务(之前的代码)
if __name__ == '__main__':
app.run(debug=True)
步骤 2:创建学生列表模板templates/student_list.html
html
<!-- templates/student_list.html -->
{% extends "base.html" %}
{% block title %}学生列表 - 学生成绩管理系统{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>学生成绩列表</h2>
<p class="text-muted">总学生数:{{ total_students }} 人 | 总课程数:{{ total_courses }} 门</p>
</div>
<!-- 学生成绩表格 -->
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr>
<th>学生姓名</th>
<th>年龄</th>
<th>课程名称</th>
<th>成绩(分)</th>
<th>成绩等级</th>
</tr>
</thead>
<tbody>
<!-- 循环渲染学生数据 -->
{% for student in students %}
<tr>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.course_name }}</td>
<td>{{ student.course_score }}</td>
<td>
<!-- 根据等级显示不同颜色 -->
{% if student.grade == 'A级(90+)' %}
<span class="badge bg-success">{{ student.grade }}</span>
{% elif student.grade == 'B级(80-89)' %}
<span class="badge bg-warning">{{ student.grade }}</span>
{% else %}
<span class="badge bg-danger">{{ student.grade }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
运行测试:
- 确保
students_data.csv在项目根目录; - 运行
app.py,访问http://localhost:5000/student/list,就能看到:- 顶部显示总学生数和课程数;
- 美观的表格,展示每个学生的姓名、年龄、课程、成绩;
- 成绩等级用不同颜色的标签显示(A 级绿色、B 级黄色、C 级红色)。
四、Flask + 可视化:Web 页面展示图表
上一篇咱们生成了柱状图、饼图,但只能存在本地文件。现在要让这些图表在 Web 页面展示,步骤是:
- 在 Flask 中生成图表,保存到
static/images/文件夹; - 在模板中引用静态文件夹的图片路径,渲染到页面。
1. 修改app.py,添加可视化报告路由
python
# app.py(新增代码,放在student_list路由后面)
import matplotlib.pyplot as plt
import seaborn as sns
import os
# 配置中文字体(避免图表中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
sns.set_style("whitegrid")
# 确保static/images文件夹存在(不存在则创建)
if not os.path.exists('static/images'):
os.makedirs('static/images')
# 新增:可视化报告路由
@app.route('/report')
def report():
# 1. 读取数据(复用之前的逻辑)
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 2. 生成各科平均分柱状图
course_avg = df.groupby('course_name')['course_score'].mean().round(1)
fig, ax = plt.subplots(figsize=(6, 4), dpi=100)
bars = ax.bar(course_avg.index, course_avg.values, color='skyblue', edgecolor='black')
ax.set_title('各科平均分对比', fontsize=12)
ax.set_xlabel('课程名称')
ax.set_ylabel('平均分(分)')
ax.set_ylim(80, 90)
# 添加数值标签
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x()+bar.get_width()/2, height+0.5, str(height), ha='center', va='bottom')
# 保存图表到static/images
plt.savefig('static/images/course_avg.png', bbox_inches='tight')
plt.close() # 关闭图表,释放内存
# 3. 生成成绩等级分布饼图
grade_count = df['grade'].value_counts()
fig, ax = plt.subplots(figsize=(6, 6), dpi=100)
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
wedges, texts, autotexts = ax.pie(
grade_count.values, labels=grade_count.index, autopct='%1.1f%%',
startangle=90, colors=colors, explode=(0.05, 0, 0)
)
ax.set_title('成绩等级分布', fontsize=12)
for autotext in autotexts:
autotext.set_color('white')
plt.savefig('static/images/grade_pie.png', bbox_inches='tight')
plt.close()
# 4. 渲染报告模板,传递图表路径
return render_template('report.html')
2. 创建可视化报告模板templates/report.html
html
<!-- templates/report.html -->
{% extends "base.html" %}
{% block title %}可视化报告 - 学生成绩管理系统{% endblock %}
{% block content %}
<h2>学生成绩可视化报告</h2>
<p class="text-muted mb-4">基于学生成绩数据生成的图表分析</p>
<!-- 图表展示(2行1列,响应式布局) -->
<div class="row g-4">
<!-- 柱状图:各科平均分 -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">各科平均分对比</h5>
<!-- 引用静态文件夹的图片:url_for('static', filename='图片路径') -->
<img src="{{ url_for('static', filename='images/course_avg.png') }}"
alt="各科平均分柱状图" class="img-fluid">
</div>
</div>
</div>
<!-- 饼图:成绩等级分布 -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">成绩等级分布</h5>
<img src="{{ url_for('static', filename='images/grade_pie.png') }}"
alt="成绩等级饼图" class="img-fluid">
</div>
</div>
</div>
</div>
{% endblock %}
关键说明:
url_for('static', filename='images/course_avg.png'):Flask 的辅助函数,自动生成静态文件的 URL,避免手动写路径出错;img-fluid:Bootstrap 的类,让图片自适应页面宽度,在手机上也能正常显示;card shadow-sm:给图表加卡片样式和阴影,让页面更有层次感。
运行测试:
访问http://localhost:5000/report,就能看到两个图表在 Web 页面上展示,和之前本地生成的一样,但现在任何人都能通过浏览器访问。
五、交互功能:学生成绩查询
只展示还不够,还要支持 “用户输入姓名,查询该学生的成绩”。这需要用到 Flask 的表单处理,接收用户输入的姓名,查询数据后返回结果。
1. 修改app.py,添加查询路由
python
# app.py(新增代码,放在report路由后面)
from flask import request # 新增request对象,用于接收请求数据
# 新增:学生查询路由(支持GET和POST请求)
@app.route('/student/search', methods=['GET', 'POST'])
def student_search():
# 如果是GET请求(用户刚访问页面),返回空结果的表单
if request.method == 'GET':
return render_template('student_search.html')
# 如果是POST请求(用户提交表单),处理查询
elif request.method == 'POST':
# 1. 获取用户输入的姓名(从表单中取name为'student_name'的值)
student_name = request.form.get('student_name', '').strip()
# 2. 验证输入(不能为空)
if not student_name:
return render_template('student_search.html', error='请输入学生姓名!')
# 3. 读取数据并查询
df = pd.read_csv('students_data.csv', encoding='utf-8', dtype={'course_score': int})
df['grade'] = df['course_score'].apply(
lambda x: 'A级(90+)' if x >= 90 else ('B级(80-89)' if x >= 80 else 'C级(<80)')
)
# 筛选该学生的数据
student_df = df[df['name'] == student_name]
# 4. 处理查询结果
if student_df.empty:
# 没有找到该学生
return render_template(
'student_search.html',
error=f'未找到名为“{student_name}”的学生',
input_name=student_name # 回显用户输入的姓名
)
else:
# 找到学生,转换为字典列表
student_data = student_df.to_dict('records')
# 计算该学生的总分和平均分
total_score = student_df['course_score'].sum()
avg_score = student_df['course_score'].mean().round(1)
return render_template(
'student_search.html',
student=student_data, # 学生成绩数据
total_score=total_score, # 总分
avg_score=avg_score, # 平均分
input_name=student_name # 回显用户输入的姓名
)
2. 创建查询模板templates/student_search.html
html
<!-- templates/student_search.html -->
{% extends "base.html" %}
{% block title %}学生查询 - 学生成绩管理系统{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<h2>学生成绩查询</h2>
<!-- 成绩查询表单 -->
<form method="POST" class="mt-4">
<div class="input-group mb-3">
<input type="text" name="student_name" class="form-control"
placeholder="请输入学生姓名(如:小明)"
value="{{ input_name if input_name else '' }}"> <!-- 回显输入 -->
<button class="btn btn-primary" type="submit">查询</button>
</div>
<!-- 显示错误信息(如果有) -->
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
</form>
<!-- 显示查询结果(如果有) -->
{% if student %}
<div class="card mt-4">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">
{{ input_name }} 的成绩详情
<span class="float-end">总分:{{ total_score }} | 平均分:{{ avg_score }}</span>
</h5>
</div>
<div class="card-body">
<table class="table table-sm mb-0">
<thead>
<tr>
<th>课程名称</th>
<th>成绩(分)</th>
<th>成绩等级</th>
</tr>
</thead>
<tbody>
{% for item in student %}
<tr>
<td>{{ item.course_name }}</td>
<td>{{ item.course_score }}</td>
<td>
{% if item.grade == 'A级(90+)' %}
<span class="badge bg-success">{{ item.grade }}</span>
{% elif item.grade == 'B级(80-89)' %}
<span class="badge bg-warning">{{ item.grade }}</span>
{% else %}
<span class="badge bg-danger">{{ item.grade }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
关键功能说明:
- 请求方法:
methods=['GET', 'POST']表示该路由支持两种请求:GET(访问页面)、POST(提交表单); - 表单回显:
value="{{ input_name if input_name else '' }}"让用户查询失败时,输入框保留之前的内容,不用重新输入; - 错误提示:用 Bootstrap 的
alert-danger类显示错误信息(如 “未找到学生”),用户体验更好。
运行测试:
- 访问
http://localhost:5000/student/search; - 输入 “小明”,点击查询,会显示小明的课程、成绩、总分和平均分;
- 输入 “不存在的名字”,会显示错误提示 “未找到该学生”。
六、完整项目实战:在线学生成绩管理系统
现在,咱们的系统已经有了 4 个核心功能:首页、学生列表、可视化报告、成绩查询。最后,把导航栏和所有功能串联起来,确保用户能通过导航在各个页面间切换(之前的base.html已经做好了导航栏)。
最终项目结构回顾
plaintext
student_web/
├── app.py # 主程序(路由、数据处理、图表生成)
├── students_data.csv # 学生数据(数据源)
├── templates/
│ ├── base.html # 基础模板(导航栏、底部)
│ ├── index.html # 首页(系统简介)
│ ├── student_list.html # 学生列表(所有成绩表格)
│ ├── student_search.html # 成绩查询(交互功能)
│ └── report.html # 可视化报告(图表展示)
└── static/
└── images/
├── course_avg.png # 柱状图(自动生成)
└── grade_pie.png # 饼图(自动生成)
运行完整系统的步骤
- 确保所有文件按上述结构存放;
- 安装所有依赖(flask、pandas、matplotlib、seaborn);
- 运行
python app.py,打开浏览器访问http://localhost:5000/; - 通过导航栏切换 “首页→学生列表→成绩查询→可视化报告”,测试所有功能。
七、新手必踩的 5 个坑:避坑指南
Flask 开发虽然简单,但新手容易在 “路径”“请求处理”“静态文件” 上踩坑,总结如下:
坑 1:模板路径错误(找不到 HTML 文件)
python
# 错误示例:模板不在templates文件夹,或文件名写错
return render_template('studentlist.html') # 错误:正确文件名是student_list.html
解决:
- 模板必须放在
templates文件夹(名字不能错,全小写); - 渲染时文件名必须和实际一致,包括下划线、大小写(Flask 区分大小写)。
坑 2:静态文件引用错误(图表不显示)
html
<!-- 错误示例:直接写本地路径,Flask无法识别 -->
<img src="static/images/course_avg.png">
解决:用url_for生成静态文件 URL:
html
<img src="{{ url_for('static', filename='images/course_avg.png') }}">
坑 3:请求方法错误(表单提交没反应)
python
# 错误示例:路由只支持GET,无法处理POST请求
@app.route('/student/search') # 默认methods=['GET']
def student_search():
if request.method == 'POST': # 永远不会执行
pass
解决:路由必须显式指定支持 POST:
python
@app.route('/student/search', methods=['GET', 'POST'])
坑 4:数据读取路径错误(找不到 CSV 文件)
python
# 错误示例:CSV文件不在项目根目录,Pandas找不到
df = pd.read_csv('data/students_data.csv') # 错误:路径不对
解决:
-
确保
students_data.csv在app.py所在的根目录; -
或用绝对路径(不推荐,换电脑会失效):
python
import os csv_path = os.path.join(os.path.dirname(__file__), 'students_data.csv') df = pd.read_csv(csv_path)
坑 5:调试模式关闭(修改代码不生效)
python
# 错误示例:debug=False,修改代码后需要手动重启服务
app.run(debug=False)
解决:开发时务必开启调试模式:
python
app.run(debug=True)
注意:生产环境(给别人正式使用时)要关闭debug=True,否则有安全风险。
八、小结与下一篇预告
这篇你学到了什么?
- Flask 基础:理解路由、视图函数、模板的核心概念,跑通 Web 服务;
- 模板开发:用 Jinja2 模板继承减少重复代码,引入 Bootstrap 美化页面;
- 数据整合:把 Pandas 本地数据处理逻辑迁移到 Flask,渲染成 Web 表格;
- 可视化 Web 化:在 Flask 中生成图表,保存到静态文件夹,在页面展示;
- 交互功能:用 request 处理表单提交,实现学生成绩查询,提升用户体验;
- 项目实战:构建完整的在线学生成绩管理系统,掌握 Web 项目的文件结构和开发流程。
下一篇预告
今天的 Flask 应用已经能通过浏览器访问,但数据还是存在本地 CSV 文件中,多人同时修改会冲突,而且无法持久化存储新数据(比如新增学生)。下一篇咱们会学 Python 的数据库操作,用SQLite(轻量级数据库,无需安装)替换 CSV 文件,实现数据的增删改查,让 Web 应用真正支持多人协作,成为生产级别的系统。
如果这篇内容帮你搭建了第一个 Flask 应用,欢迎在评论区分享你的系统截图或遇到的问题,咱们一起交流进步~
- 点赞
- 收藏
- 关注作者
评论(0)