Python课程期末项目,小白一个
【学生信息维护系统项目概述】
学生管理系统是一个基于 Python 的 Flask + MySQL 项目,旨在实现对学生信息的管理和查询。该系统主要包括学生信息录入、信息查询、信息修改和信息删除,信息可视化等功能,以提高学校或教育机构对学生信息的管理效率和准确性。
【功能要求】
- 学生信息录入:管理员可以添加学生信息,包括学生学号、姓名、性别、年龄等。
- 学生信息查询:管理员可以根据学生姓名、学号条件进行学生信息的查询,并展示查询结果。
- 学生信息修改:管理员可以根据学生学号进行学生信息的修改,包括姓名、性别、年龄等。
- 学生信息删除:管理员可以根据学生学号进行学生信息的删除操作。
- 学生信息排序:管理员可以根据学生年龄进行学生信息的升序排序
- 数据统计与分析:系统可以进行学生信息的统计和分析,如统计男女性别比例,并以饼状图显示
- 登录与访问控制:系统需要实现用户登录功能,并对访问系统的权限进行控制,确保只有授权用户可以进行相关操作
【运行视频】
【项目结构】
templates放的是前端代码,static是前端页面的美化文件,chart.png是生成的性别比例饼图
【数据库】
使用的MySQL数据库,8.0.26版本
数据库名flask,表名student
【登录功能】
登录功能没有使用数据库连接,直接写死了
可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。
@app.route('/login', methods=['GET', 'POST']) # 登录功能
def user_login():
if request.method == 'GET':
return render_template('login.html')
username = request.form.get('username')
password = request.form.get('password')
if username == 'admin' and password == '123':
return redirect(url_for('admin'))
elif username == '' or password == '':
js_code = "<script>alert('请输入账号密码!'); history.back();</script>"
return js_code
else:
js_code = "<script>alert('登陆失败!'); history.back();</script>"
return js_code
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8"/>
<title>Login</title>
<link rel="stylesheet" type="text/css" href="../static/css/index.css"/>
<link rel="stylesheet" type="text/css" href="../static/css/iconfont.css"/>
</head>
<body>
<form action="/login" method="post">
<div id="login-box">
<h1>Login</h1>
<div class="input-box">
<i class="iconfont"></i>
<input name="username" type="text" class="loginuser" value="" placeholder="UserName"/>
</div>
<div class="input-box">
<i class="iconfont"></i>
<input name="password" type="password" class="loginpwd" value="" placeholder="UserPassword"/>
</div>
<button type="submit" class="btn btn-primary">登录</button>
</div>
</form>
</body>
</html>
【添加学生信息】
通过前端获取的信息进行判断,再进入数据库
@app.route('/add', methods=['GET', 'POST']) # 添加学生
def add():
if request.method == 'GET':
return render_template('add.html')
else:
id = request.form.get('id')
name = request.form.get('name')
sex = request.form.get('sex')
age = request.form.get('age')
stu = getStudent(id)
if id == "" or name == "" or sex == "" or age == "":
js_code = "<script>alert('请填写完整信息!'); history.back();</script>"
return js_code
elif stu:
js_code = "<script>alert('学生已存在!'); history.back();</script>"
return js_code
else:
addstudent(id, name, sex, age)
return redirect(url_for('admin'))
def addstudent(id, name, sex, age):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "insert into student (id,name,sex,age) values ('" + id + "','" + name + "','" + sex + "','" + age + "')"
cursor.execute(sql)
db.commit()
db.close()
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8"/>
<title>新增数据</title>
<link rel="stylesheet" type="text/css" href="../static/css/bootstrap.css"/>
</head>
<body>
<form action="/add" style="width: 400px; margin: 100px auto" method="post">
<div class="mb-3">
<label for="id" class="form-label">学号</label>
<input type="text" class="form-control" id="id" aria-describedby="emailHelp" name="id">
</div>
<div class="mb-3">
<label for="name" class="form-label">姓名</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="mb-3">
<label for="english" class="form-label">性别</label>
<input type="text" class="form-control" id="sex" name="sex">
</div>
<div class="mb-3">
<label for="python" class="form-label">年龄</label>
<input type="text" class="form-control" id="age" name="age">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
</body>
</html>
【删除学生信息】
通过判断获取id是否存在数据库中进行删除操作
@app.route('/delete/<id>', methods=['GET']) # 删除学生
def delete(id):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "delete from student where id=" + str(id)
cursor.execute(sql)
db.commit()
db.close()
return redirect(url_for('admin'))
<form action="/delete/{{ stu[0] }}" method="get" style="display: inline-block;">
<button type="submit" class="btn btn-outline-danger btn-sm">删除</button>
</form>
【修改学生信息】
先根据学生id读取数据库学生信息,显示在前端表单
再获取修改后的信息,更新数据库
@app.route('/modify/<id>', methods=['GET', 'POST']) # 修改学生
def modify(id):
if request.method == 'GET':
students = getStudents()
editStudent = getStudent(id)
id = editStudent[0]
name = editStudent[1]
sex = editStudent[2]
age = editStudent[3]
return render_template('modify.html', students=students, id=id, name=name, sex=sex, age=age)
else:
id = request.form.get('id')
name = request.form.get('name')
sex = request.form.get('sex')
age = request.form.get('age')
if name == '' or sex == '' or age == '':
js_code = "<script>alert('请输入修改信息!'); history.back();</script>"
return js_code
else:
updateStudent(id, name, sex, age)
return redirect(url_for('admin'))
def updateStudent(id, name, sex, age):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "update student set name='%s',sex='%s', age='%s' WHERE id=%s" % (name, sex, age, id)
cursor.execute(sql)
print(sql)
db.commit()
db.close()
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8"/>
<title>修改数据</title>
<link rel="stylesheet" type="text/css" href="../static/css/bootstrap.css"/>
</head>
<body>
<form action="/modify/{{ id }}" style="width: 400px; margin: 100px auto" method="post">
<div class="mb-3">
<label for="id" class="form-label">学号</label>
<input type="text" class="form-control" id="id" name="id" value="{{ id }}"readonly>
</div>
<div class="mb-3">
<label for="name" class="form-label">姓名</label>
<input type="text" class="form-control" id="name" name="name" value="{{ name }}">
</div>
<div class="mb-3">
<label for="english" class="form-label">性别</label>
<input type="text" class="form-control" id="sex" name="sex" value="{{ sex }}">
</div>
<div class="mb-3">
<label for="python" class="form-label">年龄</label>
<input type="text" class="form-control" id="age" name="age" value="{{ age }}">
</div>
<button type="submit" class="btn btn-primary">修改</button>
</form>
</body>
</html>
【查询学生信息】
根据姓名查询为模糊查询
根据学号查询诶精准查询
@app.route('/search', methods=['POST']) # 查询学生
def search():
if request.form.get('name') != '': # 根据姓名查询
name = request.form.get('name')
students = searchstudents(name)
return render_template('admin.html', student=students)
elif request.form.get('id') != '': # 根据学号查询
id = request.form.get('id')
students1 = searchstu1(id)
return render_template('admin.html', student=students1)
elif request.form.get('id') == '' and request.form.get('name') == '':
js_code = "<script>alert('请输入查询内容!'); history.back();</script>"
return js_code
def searchstudents(name):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student where name like '%" + name + "%'"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print(row[1])
db.close()
return rows
def searchstu1(id):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = f"select * from student where id={id}"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print(row[1])
db.close()
return rows
<form action="/search" class="row g-3" method="post">
<div class="col-auto">
<label class="visually-hidden">学号</label>
<input type="text" class="form-control" name="id" placeholder="学号">
</div>
<div class="col-auto">
<label class="visually-hidden">姓名</label>
<input type="text" class="form-control" name="name" placeholder="姓名">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-outline-success mb-3">查找</button>
</div>
</form>
【排序学生信息】
读取学生年龄,ASC升序排序
@app.route('/sort', methods=['GET']) # 根据年龄排序
def sort():
students = get_Sort_Students()
return render_template('admin.html', student=students)
def get_Sort_Students():
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student order by age asc"
cursor.execute(sql)
row = cursor.fetchall()
db.close()
return row
<form action="/sort" class="row g-3">
<div class="col-auto">
<button type="submit" class="btn btn-outline-info mb-3">排序</button>
</div>
</form>
【学生信息可视化】
将数据库读取到的性别比例写为列表,再创建饼图
@app.route('/home')
def home():
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
query = "select sex, count(*) from student group by sex"
cursor.execute(query)
data = cursor.fetchall()
# 将查询结果转换为列表形式
gender_data = [{'gender': row[0], 'count': row[1]} for row in data]
cursor.close()
db.close()
# 提取性别列表和数量列表
genders = [row['gender'] for row in gender_data]
counts = [row['count'] for row in gender_data]
explode = [0.1, 0]
# 创建饼图
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.pie(counts, labels=genders, autopct='%1.1f%%', explode=explode, shadow=True,
textprops={'fontsize': 16, 'color': 'white'})
plt.axis('equal')
# 保存饼图为图片
chart_path = 'static/chart.png'
plt.savefig(chart_path, transparent=True)
# 渲染模板并传递饼图路径
return render_template('home.html', chart_path=chart_path)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>性别比例饼图</title>
<link rel="stylesheet" href="../static/css/bootstrap.css">
</head>
<body>
<div class="container">
<div class="row align-items-start">
<div class="col">
<ul class="nav flex-column" style="width: 120px; margin: 40px auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/admin">管理功能</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/home">可视化功能</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login">退出登录</a>
</li>
</ul>
</div>
<div class="col">
<div class="text-center" style="width: 933px; margin: 15px auto">
<h1>性别比例饼图</h1>
<img src="{{ chart_path }}" alt="Gender Chart">
</div>
</div>
</div>
</div>
</body>
</html>
【完整代码】
manage.py
# -*- coding: utf-8 -*-
# time: 2023/6/18 10:09
# file: manage.py
# author: sober
import matplotlib
from flask import Flask, request, render_template, redirect, url_for
import pymysql
from matplotlib import pyplot as plt
app = Flask(__name__)
dbhost = '127.0.0.1'
dbuser = 'root'
dbpass = '123456'
dbname = 'flask'
def getStudents():
# 打开数据库连接 主机地址 用户名 密码 数据库
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student"
cursor.execute(sql)
rows = cursor.fetchall()
db.close()
return rows
def getStudent(id):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student where id=" + str(id)
cursor.execute(sql)
row = cursor.fetchone()
db.close()
return row
@app.route('/')
def index():
return redirect(url_for('user_login'))
@app.route('/login', methods=['GET', 'POST']) # 登录功能
def user_login():
if request.method == 'GET':
return render_template('login.html')
username = request.form.get('username')
password = request.form.get('password')
if username == 'admin' and password == '123':
return redirect(url_for('admin'))
elif username == '' or password == '':
js_code = "<script>alert('请输入账号密码!'); history.back();</script>"
return js_code
else:
js_code = "<script>alert('登陆失败!'); history.back();</script>"
return js_code
@app.route('/admin', methods=['POST', 'GET']) # 管理功能
def admin():
students = getStudents()
return render_template('admin.html', student=students)
@app.route('/home')
def home():
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
query = "select sex, count(*) from student group by sex"
cursor.execute(query)
data = cursor.fetchall()
# 将查询结果转换为列表形式
gender_data = [{'gender': row[0], 'count': row[1]} for row in data]
cursor.close()
db.close()
# 提取性别列表和数量列表
genders = [row['gender'] for row in gender_data]
counts = [row['count'] for row in gender_data]
explode = [0.1, 0]
# 创建饼图
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.pie(counts, labels=genders, autopct='%1.1f%%', explode=explode, shadow=True,
textprops={'fontsize': 16, 'color': 'white'})
plt.axis('equal')
# 保存饼图为图片
chart_path = 'static/chart.png'
plt.savefig(chart_path, transparent=True)
# 渲染模板并传递饼图路径
return render_template('home.html', chart_path=chart_path)
@app.route('/add', methods=['GET', 'POST']) # 添加学生
def add():
if request.method == 'GET':
return render_template('add.html')
else:
id = request.form.get('id')
name = request.form.get('name')
sex = request.form.get('sex')
age = request.form.get('age')
stu = getStudent(id)
if id == "" or name == "" or sex == "" or age == "":
js_code = "<script>alert('请填写完整信息!'); history.back();</script>"
return js_code
elif stu:
js_code = "<script>alert('学生已存在!'); history.back();</script>"
return js_code
else:
addstudent(id, name, sex, age)
return redirect(url_for('admin'))
def addstudent(id, name, sex, age):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "insert into student (id,name,sex,age) values ('" + id + "','" + name + "','" + sex + "','" + age + "')"
cursor.execute(sql)
db.commit()
db.close()
@app.route('/sort', methods=['GET']) # 根据年龄排序
def sort():
students = get_Sort_Students()
return render_template('admin.html', student=students)
def get_Sort_Students():
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student order by age asc"
cursor.execute(sql)
row = cursor.fetchall()
db.close()
return row
@app.route('/search', methods=['POST']) # 查询学生
def search():
if request.form.get('name') != '': # 根据姓名查询
name = request.form.get('name')
students = searchstudents(name)
return render_template('admin.html', student=students)
elif request.form.get('id') != '': # 根据学号查询
id = request.form.get('id')
students1 = searchstu1(id)
return render_template('admin.html', student=students1)
elif request.form.get('id') == '' and request.form.get('name') == '':
js_code = "<script>alert('请输入查询内容!'); history.back();</script>"
return js_code
def searchstudents(name):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "select * from student where name like '%" + name + "%'"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print(row[1])
db.close()
return rows
def searchstu1(id):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = f"select * from student where id={id}"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
print(row[1])
db.close()
return rows
@app.route('/modify/<id>', methods=['GET', 'POST']) # 修改学生
def modify(id):
if request.method == 'GET':
students = getStudents()
editStudent = getStudent(id)
id = editStudent[0]
name = editStudent[1]
sex = editStudent[2]
age = editStudent[3]
return render_template('modify.html', students=students, id=id, name=name, sex=sex, age=age)
else:
id = request.form.get('id')
name = request.form.get('name')
sex = request.form.get('sex')
age = request.form.get('age')
if name == '' or sex == '' or age == '':
js_code = "<script>alert('请输入修改信息!'); history.back();</script>"
return js_code
else:
updateStudent(id, name, sex, age)
return redirect(url_for('admin'))
def updateStudent(id, name, sex, age):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "update student set name='%s',sex='%s', age='%s' WHERE id=%s" % (name, sex, age, id)
cursor.execute(sql)
print(sql)
db.commit()
db.close()
@app.route('/delete/<id>', methods=['GET']) # 删除学生
def delete(id):
db = pymysql.connect(host=dbhost, user=dbuser, password=dbpass, database=dbname)
cursor = db.cursor()
sql = "delete from student where id=" + str(id)
cursor.execute(sql)
db.commit()
db.close()
return redirect(url_for('admin'))
if __name__ == '__main__':
app.run('127.0.0.1', 5002, debug=True)
admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生信息管理</title>
<link rel="stylesheet" href="../static/css/bootstrap.css">
</head>
<body>
<div class="container">
<div class="row align-items-start">
<div class="col">
<ul class="nav flex-column " style="width: 120px; margin: 40px auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/admin">管理功能</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/home">可视化功能</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login" >退出登录</a>
</li>
</ul>
</div>
<div class="col">
<table class="table" style="width: 900px; margin: 40px auto">
<thead>
<tr>
<th scope="col">
<form action="/search" class="row g-3" method="post">
<div class="col-auto">
<label class="visually-hidden">学号</label>
<input type="text" class="form-control" name="id" placeholder="学号">
</div>
<div class="col-auto">
<label class="visually-hidden">姓名</label>
<input type="text" class="form-control" name="name" placeholder="姓名">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-outline-success mb-3">查找</button>
</div>
</form>
</th>
<th scope="col">
<form action="/add" class="row g-3">
<div class="col-auto">
<button type="submit" class="btn btn-outline-info mb-3">添加学生</button>
</div>
</form>
</th>
<th scope="col">
<form action="/sort" class="row g-3">
<div class="col-auto">
<button type="submit" class="btn btn-outline-info mb-3">排序</button>
</div>
</form>
</th>
<th scope="col">
<form action="/admin" class="row g-3">
<div class="col-auto">
<button type="submit" class="btn btn-outline-info mb-3">返回</button>
</div>
</form>
</th>
</tr>
</thead>
<tr>
<td colspan="4">
<div class="table-responsive">
<table class="table table-hover" style="width: 900px; margin: 0 auto">
<thead>
<tr>
<th scope="col">学号</th>
<th scope="col">姓名</th>
<th scope="col">性别</th>
<th scope="col">年龄</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
{#
需要将 Python 对象的数据显示到浏览器上, 模板语法
jinja2(flask) numjucks(javascript) moka(django) vue
jinja2 可以直接在HTML中写 Python 的逻辑
#}
{% for stu in student %}
<tr>
<th>{{ stu[0] }}</th>
<td>{{ stu[1] }}</td>
<td>{{ stu[2] }}</td>
<td>{{ stu[3] }}</td>
<td>
<form action="/delete/{{ stu[0] }}" method="get"
style="display: inline-block;">
<button type="submit" class="btn btn-outline-danger btn-sm">删除
</button>
</form>
<form action="/modify/{{ stu[0] }}" method="get"
style="display: inline-block;">
<button type="submit" class="btn btn-outline-warning btn-sm">修改
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>
【项目截图】