当前位置: 首页 > news >正文

管理系统模板

在 Web 开发学习过程中,亲手搭建一个功能完整的管理系统是巩固技术栈的绝佳方式。本文将带大家从零开始,用 HTML+JS+CSS 搭建前端界面,结合 Flask 后端框架与 SQLite 数据库,开发一个轻量实用的学生管理系统,适合全栈初学者参考实践。

技术栈解析​

  • 前端三剑客:HTML 构建页面结构,CSS 实现响应式布局与美化,JavaScript 处理表单验证、动态交互(如数据加载、删除确认)。​
  • 后端框架:Flask(Python),轻量级 Web 框架,路由配置简单,适合小型项目快速开发,无需复杂配置即可连接前端与数据库。​
  • 数据库:SQLite,无需独立服务的文件型数据库,自带 Python 标准库,与 Flask 结合紧密,适合开发阶段和小规模应用。​

这套组合的优势在于轻量易部署,无需额外安装数据库服务,单文件即可运行,对新手友好度拉满。

系统功能设计与架构​

核心功能模块​

  1. 用户登录:验证管理员身份(简化版可跳过注册,直接使用预设账号)。​
  1. 学生信息管理:​
  • 列表展示:学号、姓名、性别、年龄、班级等字段。​
  • 增删改查:添加新学生、编辑已有信息、删除退学学生、按学号 / 姓名搜索。​
  1. 数据持久化:所有操作实时同步到 SQLite 数据库,刷新页面不丢失数据。​

架构流程​

前端页面(HTML+CSS) ←→ JavaScript(交互/请求) ←→ Flask后端(路由/逻辑) ←→ SQLite数据库(存储)​

  • 前端通过 Ajax 发送请求(如添加学生时提交表单数据)。​
  • Flask 接收请求后,调用数据库操作函数(增删改查)。​
  • 数据库返回结果,Flask 处理后将数据以 JSON 或渲染模板的形式返回给前端。​
  • 前端更新页面显示(如刷新列表、提示操作结果)。

核心代码实现​

from flask import Flask, render_template, request, redirect, url_for, session, send_file, flash
import sqlite3, os, csv
from werkzeug.security import generate_password_hash, check_password_hashapp = Flask(__name__)
app.secret_key = 'super-secret-key'DB_PATH = 'database/students.db'# --- DB 初始化 ---
def init_db():if not os.path.exists('database'):os.makedirs('database')conn = sqlite3.connect(DB_PATH)cursor = conn.cursor()cursor.execute('''CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE,password TEXT,role TEXT DEFAULT 'user')''')cursor.execute('''CREATE TABLE IF NOT EXISTS students (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,age INTEGER,grade TEXT,score REAL)''')conn.commit()conn.close()# 添加默认管理员账户(如果不存在)conn = sqlite3.connect(DB_PATH)cursor = conn.cursor()cursor.execute("SELECT COUNT(*) FROM users WHERE username = 'admin'")if cursor.fetchone()[0] == 0:hashed_password = generate_password_hash('admin123')cursor.execute("INSERT INTO users (username, password, role) VALUES (?, ?, ?)", ('admin', hashed_password, 'admin'))conn.commit()conn.close()# --- DB 操作函数 ---
def get_db():conn = sqlite3.connect(DB_PATH)conn.row_factory = sqlite3.Rowreturn conn# --- 首页重定向 ---
@app.route('/')
def index():return redirect(url_for('login'))# --- 注册 ---
@app.route('/register', methods=['GET', 'POST'])
def register():if request.method == 'POST':username = request.form['username']password = generate_password_hash(request.form['password'])try:conn = get_db()conn.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, password))conn.commit()flash('注册成功,请登录', 'success')return redirect(url_for('login'))except:flash('用户名已存在', 'danger')return render_template('register.html')# --- 登录 ---
@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password_input = request.form['password']conn = get_db()user = conn.execute('SELECT * FROM users WHERE username = ?', (username,)).fetchone()if user and check_password_hash(user['password'], password_input):session['user'] = usernamesession['role'] = user['role']  # 保存用户角色return redirect(url_for('dashboard'))flash('用户名或密码错误', 'danger')return render_template('login.html')# --- 登出 ---
@app.route('/logout')
def logout():session.pop('user', None)return redirect(url_for('login'))# --- 学生信息主页面 ---
@app.route('/dashboard')
def dashboard():if 'user' not in session:return redirect(url_for('login'))conn = get_db()students = conn.execute('SELECT * FROM students').fetchall()return render_template('dashboard.html', students=students)# --- 数据库管理页面 ---
@app.route('/db_admin')
def db_admin():# 检查用户权限if 'user' not in session or session.get('role') != 'admin':flash('权限不足', 'danger')return redirect(url_for('dashboard'))databases = list_databases()return render_template('db_admin.html', databases=databases)# --- 创建新数据库 ---
@app.route('/create_db', methods=['POST'])
def create_db():# 检查用户权限if 'user' not in session or session.get('role') != 'admin':flash('权限不足', 'danger')return redirect(url_for('dashboard'))db_name = request.form.get('db_name')if db_name:try:db_path = create_new_database(db_name)flash(f'数据库 {db_name} 创建成功', 'success')except Exception as e:flash(f'创建数据库失败: {str(e)}', 'danger')else:flash('数据库名称不能为空', 'danger')return redirect(url_for('db_admin'))# --- 删除数据库 ---
@app.route('/delete_db/<db_name>')
def delete_db(db_name):# 检查用户权限if 'user' not in session or session.get('role') != 'admin':flash('权限不足', 'danger')return redirect(url_for('dashboard'))if db_name != 'students':  # 防止删除主数据库if delete_database(db_name):flash(f'数据库 {db_name} 删除成功', 'success')else:flash(f'数据库 {db_name} 删除失败', 'danger')else:flash('不能删除主数据库', 'danger')return redirect(url_for('db_admin'))# --- 查看数据库详情 ---
@app.route('/db_info/<db_name>')
def db_info(db_name):# 检查用户权限if 'user' not in session or session.get('role') != 'admin':flash('权限不足', 'danger')return redirect(url_for('dashboard'))info = get_database_info(db_name)if info:return render_template('db_info.html', info=info)else:flash('数据库不存在', 'danger')return redirect(url_for('db_admin'))# --- 添加学生 ---
# 关键修改:添加 'GET' 方法支持
@app.route('/add_student', methods=['GET', 'POST'])
def add_student():# 如果是GET请求,显示新增学生表单if request.method == 'GET':return render_template('addstudent.html')# 如果是POST请求,处理表单提交(原逻辑)name = request.form['name']age = request.form['age']grade = request.form['grade']score = request.form['score']# 数据校验(推荐添加)try:age = int(age)score = float(score)if age <= 0 or age > 150 or score < 0 or score > 100:flash('年龄或成绩格式错误', 'error')return render_template('addstudent.html')except ValueError:flash('年龄或成绩必须为数字', 'error')return render_template('addstudent.html')# 数据库操作try:conn = get_db()conn.execute('INSERT INTO students (name, age, grade, score) VALUES (?, ?, ?, ?)',(name, age, grade, score))conn.commit()flash('学生添加成功', 'success')return redirect(url_for('dashboard'))except Exception as e:flash(f'添加失败:{str(e)}', 'error')return render_template('addstudent.html')# --- 删除学生 ---
@app.route('/delete_student/<int:id>')
def delete_student(id):conn = get_db()conn.execute('DELETE FROM students WHERE id = ?', (id,))conn.commit()return redirect(url_for('sort'))# --- 修改学生 ---
@app.route('/edit_student/<int:id>', methods=['GET', 'POST'])
def edit_student(id):conn = get_db()if request.method == 'POST':name = request.form['name']age = request.form['age']grade = request.form['grade']score = request.form['score']conn.execute('UPDATE students SET name=?, age=?, grade=?, score=? WHERE id=?',(name, age, grade, score, id))conn.commit()return redirect(url_for('sort'))student = conn.execute('SELECT * FROM students WHERE id=?', (id,)).fetchone()return render_template('edit_student.html', student=student)# --- 查询学生 ---
@app.route('/search', methods=['GET'])
def search():keyword = request.args.get('q', '')conn = get_db()students = conn.execute('SELECT * FROM students WHERE name LIKE ?', (f'%{keyword}%',)).fetchall()return render_template('dashboard.html', students=students)# --- 成绩排序 ---
@app.route('/sort')
def sort():# 获取排序参数,默认升序order = request.args.get('order', 'asc').lower()# 限定合法值,避免非法参数if order not in ['asc', 'desc']:order = 'asc'# 拼接排序 SQL(这里因排序字段和方式简单,参数化意义不大,仍用拼接但做好校验)query = f'SELECT * FROM students ORDER BY score {"ASC" if order == "asc" else "DESC"}'try:conn = get_db()students = conn.execute(query).fetchall()except Exception as e:# 捕获数据库异常,返回友好提示(可结合 flash 消息 )flash(f'查询成绩排序数据失败:{str(e)}', 'error')return redirect(url_for('dashboard'))# 传递当前排序方式到模板,用于展示和切换return render_template('score_sort.html', students=students, current_order=order)# --- 导出 CSV ---
@app.route('/export_csv')
def export_csv():conn = get_db()students = conn.execute('SELECT * FROM students').fetchall()export_path = 'export/report.csv'if not os.path.exists('export'):os.makedirs('export')with open(export_path, 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(['ID', '姓名', '年龄', '年级', '成绩'])for s in students:writer.writerow([s['id'], s['name'], s['age'], s['grade'], s['score']])return send_file(export_path, as_attachment=True)# --- 成绩可视化图表 ---
@app.route('/chart')
def chart():conn = get_db()data = conn.execute('SELECT name, score FROM students').fetchall()# 格式化成绩为保留一位小数formatted_data = [(name, round(score, 1)) for name, score in data]return render_template('chart.html', data=formatted_data)if __name__ == '__main__':init_db()app.run(debug=True)

系统截图

想要资料私信

http://www.dtcms.com/a/298567.html

相关文章:

  • 应用程序无法正常启动(0xc000007b)怎么办 解决方法详解
  • Matlab学习笔记:结构基础
  • 数仓规范体系的构建
  • SVM多分类实战:从理论到应用的完整指南
  • Linux的磁盘存储管理实操——(下二)——逻辑卷管理LVM的扩容、缩容
  • 5.2.1 javascript 事件对象.内容补充.
  • 从零本地部署使用Qwen3-coder进行编程
  • 1.1.4 建筑隔震减震设计结构要求
  • SpringBoot创建项目的方式
  • Spring AOP `MethodInvocation` 工作原理
  • JavaScript 数组的 every() 和 some() 方法使用
  • Web前端:JavaScript Math内置对象
  • 个人财务记录应用
  • SEC_FirePower 第一天作业
  • 2025年07月25日Github流行趋势
  • 【IDEA】IDEA中如何通过分支/master提交git?
  • haproxy篇
  • 扫描电镜全面解析:工作原理、应用领域与样品制备技巧
  • macbook安装homebrew
  • 为什么数组可以做到时间复杂度为O(1)的随机访问
  • jQuery ID与Class选择器对比
  • C++中的deque
  • js多边形算法:获取多边形中心点,且必定在多边形内部
  • Android系统中的4KB内存页简介
  • 【图像理解进阶】如何对图像中的小区域进行细粒度的语义分割?
  • DNS 服务正反向解析与 Web 集成实战:从配置到验证全流程
  • 37.安卓逆向2-frida hook技术-过firda检测(二)(过D-Bus检测和搭配maps检测进行使用)
  • 65.第二阶段x64游戏实战-替换游戏lua打印可接任务
  • OpenCV结合深度学习进行图像分类
  • 暑期自学嵌入式——Day08(C语言阶段)