Skip to content

学生管理平台开发实战


课程目标

  • 掌握常用的后端框架的基本安装与配置。
  • 掌握路由的定义与使用。
  • 掌握接口请求数据。
  • 掌握接口响应信息。

知识点总览

点击查看:后端开发知识点梳理


需求说明

  • 基于 flask 框架实现 Web 版学生管理系统
  • 系统基于功能需要提供 列表,添加,修改,删除,查询等功能的相关接口
  • 所有数据需通过 MySQL 数据库进行持久化存储
    • 数据表 student 包含以下字段:
      • sid: 学号,主键
      • name: 姓名
      • age: 年龄
      • gender: 性别
  • 首页接口
    • GET 请求方式返回首页页面
    • GET 请求方式返回所有学生数据
  • 添加接口
    • GET 请求方式返回添加页面
    • POST 请求方式完成添加操作,返回列表页面,包含新添加的数据
  • 修改接口
    • 所有修改相关请求需要携带要修改学生的 ID 信息
    • GET 请求方式返回修改页面
    • POST 请求方式完成修改操作,返回列表页面,包含修改后的数据
  • 删除接口
    • 所有修改相关请求需要携带要删除学生的 ID 信息
    • GET 请求方式删除指定学生信息,返回列表页面,不显示删除的数据

实战思路

uml diagram


环境准备

  • 安装 Flask 框架:pip install flask
  • 安装 PyMySQL:pip install pymysql
  • 安装 flask-cors:pip install flask-cors
  • 线上数据库
    • host:mysql.hogwarts.ceshiren.com
    • username:stu
    • password:hogwarts_stu

数据库准备

-- 创建数据表(字段根据需求去创建)
CREATE TABLE student (
    sid INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT,
    gender CHAR(10)
);

-- 插入数据
INSERT INTO student (name, age, gender) 
VALUES("Tony", 24,"male"),
("Alice",26,"female"),
("Lily", 24,"female"),
("Jack",26,"male");

项目目录结构

student_manager_flatform/
│
├── server.py                     # 主程序入口
├── static/                    # 静态文件   └── css/
│       └── style.css          # 自定义 CSS 文件
└── templates/                 # 模板文件
    ├── base.html              # 公共模板
    ├── index.html             # 首页模板
    ├── add.html             # 添加学生模板
    └── change.html       # 修改学生模板

创建 Flask 实例

创建 server.py

注意:服务器程序运行起来前,需先建立 templates 文件夹,并建立 index.html、add.html 和 change.html 三个文件。

from flask import Flask, render_template

# 创建 flask 实例
app = Flask(__name__)

# 首页接口
@app.route("/")
def index():
    return render_template("index.html")

# 添加页面接口
@app.route("/add")
def add():
    return render_template("add.html")

# 修改页面接口
@app.route("/change")
def change():
    return render_template("change.html")


if __name__ == '__main__':
    app.run(debug=True, port=5050)

学生管理系统首页 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>学生管理系统</title>
</head>
<body>
    <h2>学生管理系统</h2>
</body>
</html>
<script type="text/javascript"></script>

添加学生页面 add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>学生管理系统</title>
</head>
<body>
    <h2>添加学生</h2>
</body>
</html>
<script type="text/javascript"></script>

修改学生页面 change.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>学生管理系统</title>
</head>
<body>
    <h2>修改学生</h2>
</body>
</html>
<script type="text/javascript"></script>

页面样式

  1. 创建 static 目录
  2. 在 static 目录下创建 css 目录
  3. 创建 style.css 文件
/* ----------------------------- */
/* 基础页面样式 (base.html) */
/* ----------------------------- */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #fff3e0; /* 浅橙色背景 */
    color: #333;
}

header {
    background-color: #FF5722; /* 橙红色 */
    color: white;
    padding: 1rem;
    text-align: center;
}

header h1 {
    margin: 0;
    font-size: 2rem;
}

nav {
    margin-top: 1rem;
}

nav a {
    color: white;
    text-decoration: none;
    margin: 0 1rem;
    font-size: 1.1rem;
}

nav a:hover {
    text-decoration: underline;
}

main {
    padding: 2rem;
    max-width: 800px;
    margin: 0 auto;
    background-color: white;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
}

/* ----------------------------- */
/* 首页样式 (index.html) */
/* ----------------------------- */
h2 {
    color: #FF5722; /* 橙红色 */
    text-align: center;
    margin-bottom: 1.5rem;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 1rem;
}

table th, table td {
    padding: 0.75rem;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

table th {
    background-color: #FF5722; /* 橙红色 */
    color: white;
}

table tr:hover {
    background-color: #ffccbc; /* 浅橙红色高亮 */
}

table a {
    color: #FF5722; /* 橙红色 */
    text-decoration: none;
}

table a:hover {
    text-decoration: underline;
}

/* ----------------------------- */
/* 添加修改学生页面样式 (add.html,change.html) */
/* ----------------------------- */
form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-width: 400px;
    margin: 0 auto;
}

form label {
    font-weight: bold;
    color: #FF5722; /* 橙红色 */
}

form input[type="text"] {
    padding: 0.5rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 1rem;
}

form input[type="text"]:focus {
    border-color: #FF5722; /* 橙红色 */
    outline: none;
}

form input[type="submit"], form input[type="reset"] {
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 4px;
    font-size: 1rem;
    cursor: pointer;
}

form input[type="submit"] {
    background-color: #FF5722; /* 橙红色 */
    color: white;
}

form input[type="submit"]:hover {
    background-color: #f4511e; /* 深橙红色 */
}

form input[type="reset"] {
    background-color: #ff7043; /* 浅橙红色 */
    color: white;
}

form input[type="reset"]:hover {
    background-color: #ff5722; /* 橙红色 */
}

设置基础模版

创建 base.html,添加导航按钮,关联 css 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生管理系统</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <header>
        <h1>学生管理系统</h1>
        <nav>
            <a href="{{ url_for('index') }}">首页</a>
            <a href="{{ url_for('add') }}">添加学生</a>
        </nav>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>

改造业务页面

<!-- index.html -->
{% extends "base.html" %}

{% block content %}
<h2>欢迎来到学生管理系统</h2>
{% endblock %}
<!-- add.html -->
{% extends "base.html" %}

{% block content %}
<h2>添加学生</h2>

{% endblock %}
<!-- change.html -->
{% extends "base.html" %}

{% block content %}
<h2>修改学生</h2>

{% endblock %}

首页接口查询数据

from flask import Flask, render_template
from pymysql import Connect

# 创建 flask 实例
app = Flask(__name__)


# 连接数据库
db_connect = Connect(
    host="mysql.hogwarts.ceshiren.com",
    port=3306,
    user="stu",
    password="hogwarts_stu",
    database="hogwarts_stu",
    charset="utf8"
)

# 首页接口
@app.route("/")
def index():
    # 查询数据库得到所有的数据展示
    # 获取游标对象
    cursor = db_connect.cursor()
    # 获取全部数据要执行的 SQL 语句
    sql_str = ''' select * from student; '''
    # 执行 SQL 语句
    cursor.execute(sql_str)
    # 获取全部执行结果
    data = cursor.fetchall()
    # 定义响应数据结构
    # datas = []
    # # 处理 SQL 执行结果,拼接数据为字典,添加到响应数据列表中
    # for item in data:
    #     s = {}
    #     s["sid"] = item[0]
    #     s["name"] = item[1]
    #     s["age"] = item[2]
    #     s["gender"] = item[3]
    #     datas.append(s)
    datas = [{"sid": s[0], "name": s[1], "age": s[2], "gender": s[3]} for s in data]
    # 关闭游标
    cursor.close()
    return render_template("index.html", students=datas)

首页页面

{% extends "base.html" %}

{% block content %}
    <h2>欢迎来到学生管理系统</h2>
    <!-- 表格 -->
    <table>
        <thead>
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for stu in students %}
            <tr>
                <td>{{ stu.sid }}</td>
                <td>{{ stu.name }}</td>
                <td>{{ stu.age }}</td>
                <td>{{ stu.gender }}</td>
                <td>
                    <a href="">修改</a>
                    <a href="">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
{% endblock %}


添加数据接口

from flask import Flask, render_template, request, redirect


# 添加页面接口,添加数据接口
@app.route("/add", methods=["GET", "POST"])
def add_stu():
    # 根据请求方式区别不同的操作
    if request.method == "GET":
        return render_template("add.html")
    else:
        # 将添加提交过来的数据保存到数据库中
        name = request.values.get("name")
        age = request.values.get("age")
        gender = request.values.get("gender")
        sql_str = ''' insert into student (name, age, gender) values(%s,%s,%s) '''
        cursor = db_connect.cursor()
        cursor.execute(sql_str, [name, age, gender])
        # 提交更改操作,不提交不生效
        db_connect.commit()
        cursor.close()
        # 新增成功返回首页
        return redirect("/")

发出 POST 请求查看效果。

查看数据库中新增数据效果。


添加学生页面

{% extends "base.html" %}

{% block content %}
    <h2>添加学生</h2>
    <form action="/add" method="POST">
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" placeholder="请输入学生姓名" required><br>
        <label for="age">年龄:</label>
        <input type="text" id="age" name="age" placeholder="请输入学生年龄" required><br>
        <label for="gender">性别:</label>
        <input type="text" id="gender" name="gender" placeholder="请输入学生性别" required><br>
        <input type="reset" value="清空">
        <input type="submit" value="提交">
    </form>

{% endblock %}


修改数据接口

# 修改页面接口,修改数据接口
@app.route("/change/<sid>", methods=["GET", "POST"])
def change(sid):
    # 根据请求方式区别不同的操作
    if request.method == "GET":
        cursor = db_connect.cursor()
        sql = f'''select * from student where sid = {sid}'''
        cursor.execute(sql)
        item = cursor.fetchone()
        data = {}
        data["sid"] = item[0]
        data["name"] = item[1]
        data["age"] = item[2]
        data["gender"] = item[3]
        cursor.close()
        return render_template("change.html", student=data)
    else:
        # 将数据库中的数据找出来修改后再保存到数据库中
        # 将添加提交过来的数据保存到数据库中
        name = request.values.get("name")
        age = request.values.get("age")
        gender = request.values.get("gender")
        sql_str = ''' update student set name=%s, age=%s, gender=%s where sid = %s '''
        cursor = db_connect.cursor()
        cursor.execute(sql_str, [name, age, gender,sid])
        # 提交更改操作,不提交不生效
        db_connect.commit()
        cursor.close()
        return redirect("/")

修改学生页面

{% extends "base.html" %}

{% block content %}
    <h2>修改学生</h2>
    <form action="/change/{{ student.sid }}" method="POST">
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" value="{{ student.name }}" required><br>
        <label for="age">年龄:</label>
        <input type="text" id="age" name="age" value="{{ student.age }}" required><br>
        <label for="gender">性别:</label>
        <input type="text" id="gender" name="gender" value="{{ student.gender }}" required><br>
        <input type="reset" value="清空">
        <input type="submit" value="提交">
    </form>

{% endblock %}


删除数据接口

# 删除信息接口
@app.route("/delete/<sid>")
def delete_stu(sid):
    curosr = db_connect.cursor()
    sql = f''' delete from student where sid = {sid} '''
    curosr.execute(sql)
    db_connect.commit()
    curosr.close()
    # 删除成功后返回首页
    return redirect("/")

返回首页后,可以再次获取全部数据查看删除效果。


课后练习

点击查看课后练习


总结

  • 掌握常用的后端框架的基本安装与配置。
  • 掌握路由的定义与使用。
  • 掌握接口请求数据。
  • 掌握接口响应信息。
  • 掌握前后端分离下,如何解决跨域问题。