后端Flask + 前端Vue + Element UI 练习系统

本文介绍了如何使用Python Flask框架结合Element UI库,实现用户数据的增删改查操作,包括数据库设计和后端接口的详细代码示例。
部署运行你感兴趣的模型镜像

链接:https://pan.baidu.com/s/1nwFERM-BWE0M405ZBAG4sw 
提取码:iufp

数据库中user表设计: 

 

参考视频

vue脚手架  【编程不良人】VueCli脚手架的实战教程,已完结!_哔哩哔哩_bilibili

element ui  Vue.js极简教程第三季:Element-UI(入门、精简、不拖拉、2.x基础)——FastAPI辅助教学_哔哩哔哩_bilibili

Element - The world's most popular Vue UI framework

vue电商系统  https://www.bilibili.com/video/BV1EE411B7SU?p=1

最终简陋效果,看第一个视频做了个简易的脚手架版,后面要学element ui 又改进了一下,根据给的资料做出来不难,要是有人需要后面再传代码吧

可以实现数据库中的用户数据获取、用户信息编辑、用户删除和添加新用户

后端主要代码  app.py

from flask import Flask
from flask import request, jsonify
from common.UserModel import UserModel
import json
from flask_cors import *

app = Flask(__name__)
CORS(app, resources=r'/*')

@app.route('/user/findAll', methods=['get'])
def findAll():
    payload = []
    users = UserModel
    users_all = users.select()
    for result in users_all:
        content = {}
        content = {"id": result.id, "name": result.name,
                   "age": result.age, "bir":str(result.bir)}
        payload.append(content)

    return jsonify(payload)


@app.route('/user/findOne', methods=['get'])
def findOne():
    payload = []
    users = UserModel
    id = int(request.args.get('id'))
    users_result = users.select().where(users.id == id)
    for result in users_result:
        content = {}
        content = {"id": result.id, "name": result.name,
                   "age": result.age, "bir": str(result.bir)}
        payload.append(content)

    return jsonify(payload)

@app.route('/user/add', methods=['post'])
def add():
    response_object = {'success': 'true', 'msg':'添加成功'}

    users = UserModel
    data = json.loads(request.get_data(as_text=True))

    try:
        users.insert(name=data['name'], age=data['age'], bir=data['bir']).execute()
        return jsonify(response_object)
    except Exception as e:
        print(e)
        response_object = {'success': 'false'}
        return jsonify(response_object)


@app.route('/user/delete', methods=['get'])
def delete():
    response_object = {'success': 'true', 'msg':'用户删除成功'}

    users = UserModel
    id = request.args.get('id')

    try:
        users.delete().where(users.id==id).execute()
        return jsonify(response_object)
    except Exception as e:
        print(e)
        response_object = {'success': 'false'}
        return jsonify(response_object)


@app.route('/user/update', methods=['post'])
def update():
    response_object = {'success': 'true', 'msg':'用户信息编辑成功'}

    users = UserModel
    data = eval(request.get_data(as_text=True))

    try:
        users.update(name=data['name'], age=data['age'], bir=data['bir']).where(users.id==data['id']).execute()
        return jsonify(response_object)
    except Exception as e:
        print(e)
        response_object = {'success': 'false'}
        return jsonify(response_object)



if __name__ == '__main__':
    app.run(host='127.0.0.1',debug=True)

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

下面是一个基于 **Flask后端+ Vue3(前端+ MySQL(数据库) + Element Plus(UI组件库)** 的完整学生信息管理系统的实现方案。我们将从项目结构、环境搭建、代码实现到前后端交互进行详细说明。 --- ## ✅ 系统功能概述 - 学生信息的增删改查(CRUD) - 分页显示 - 模糊搜索(按姓名或学号) - 响应式界面 --- ## 🧱 项目结构 ``` student-system/ │ ├── backend/ # Flask 后端 │ ├── app.py │ ├── config.py │ ├── models.py │ ├── routes.py │ └── requirements.txt │ ├── frontend/ # Vue3 + Element Plus 前端 │ ├── public/ │ ├── src/ │ │ ├── assets/ │ │ ├── components/ │ │ ├── views/StudentList.vue │ │ ├── App.vue │ │ └── main.js │ ├── package.json │ └── vite.config.js │ └── database.sql # 数据库建表语句 ``` --- ## 🔧 技术栈 | 模块 | 技术 | |------------|------------------------| | 后端框架 | Flask | | 数据库 | MySQL (使用 PyMySQL) | | ORM | SQLAlchemy | | 接口 | RESTful API | | 前端框架 | Vue3 + Vite | | UI 库 | Element Plus | | 通信 | Axios | --- ## 🛠️ 第一步:创建数据库和表 ### `database.sql` ```sql CREATE DATABASE IF NOT EXISTS student_db CHARACTER SET utf8mb4; USE student_db; CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, student_id VARCHAR(20) NOT NULL UNIQUE, name VARCHAR(50) NOT NULL, gender ENUM('男', '女') NOT NULL, age INT NOT NULL, phone VARCHAR(15), email VARCHAR(100), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` 导入数据库: ```bash mysql -u root -p < database.sql ``` --- ## 🐍 第二步:Flask 后端实现 ### `backend/config.py` ```python import os class Config: SECRET_KEY = 'your-secret-key' SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:your_password@localhost/student_db' SQLALCHEMY_TRACK_MODIFICATIONS = False ``` > ⚠️ 修改 `your_password` 为你的 MySQL 密码 --- ### `backend/models.py` ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Student(db.Model): __tablename__ = 'students' id = db.Column(db.Integer, primary_key=True) student_id = db.Column(db.String(20), unique=True, nullable=False) name = db.Column(db.String(50), nullable=False) gender = db.Column(db.Enum('男', '女'), nullable=False) age = db.Column(db.Integer, nullable=False) phone = db.Column(db.String(15)) email = db.Column(db.String(100)) def to_dict(self): return { 'id': self.id, 'student_id': self.student_id, 'name': self.name, 'gender': self.gender, 'age': self.age, 'phone': self.phone, 'email': self.email } ``` --- ### `backend/routes.py` ```python from flask import Blueprint, request, jsonify from .models import db, Student api = Blueprint('api', __name__) # 获取所有学生(支持分页和搜索) @api.route('/students', methods=['GET']) def get_students(): page = request.args.get('page', 1, type=int) limit = request.args.get('limit', 10, type=int) keyword = request.args.get('keyword', '') query = Student.query if keyword: query = query.filter( db.or_( Student.name.contains(keyword), Student.student_id.contains(keyword) ) ) pagination = query.paginate(page=page, per_page=limit, error_out=False) students = [s.to_dict() for s in pagination.items] return jsonify({ 'success': True, 'data': students, 'total': pagination.total }) # 添加学生 @api.route('/students', methods=['POST']) def add_student(): data = request.json try: student = Student( student_id=data['student_id'], name=data['name'], gender=data['gender'], age=data['age'], phone=data.get('phone'), email=data.get('email') ) db.session.add(student) db.session.commit() return jsonify({'success': True, 'message': '添加成功'}) except Exception as e: db.session.rollback() return jsonify({'success': False, 'message': str(e)}), 400 # 更新学生 @api.route('/students/<int:id>', methods=['PUT']) def update_student(id): student = Student.query.get_or_404(id) data = request.json try: student.name = data['name'] student.gender = data['gender'] student.age = data['age'] student.phone = data.get('phone') student.email = data.get('email') db.session.commit() return jsonify({'success': True, 'message': '更新成功'}) except Exception as e: db.session.rollback() return jsonify({'success': False, 'message': str(e)}), 400 # 删除学生 @api.route('/students/<int:id>', methods=['DELETE']) def delete_student(id): student = Student.query.get_or_404(id) try: db.session.delete(student) db.session.commit() return jsonify({'success': True, 'message': '删除成功'}) except Exception as e: db.session.rollback() return jsonify({'success': False, 'message': str(e)}), 400 ``` --- ### `backend/app.py` ```python from flask import Flask from .config import Config from .models import db from .routes import api def create_app(): app = Flask(__name__) app.config.from_object(Config) db.init_app(app) app.register_blueprint(api, url_prefix='/api') @app.route('/') def index(): return '<h1>Student Management System Backend</h1>' return app if __name__ == '__main__': app = create_app() with app.app_context(): db.create_all() # 创建表 app.run(debug=True) ``` --- ### 安装依赖(`backend/requirements.txt`) ```txt Flask==2.3.3 Flask-SQLAlchemy==3.0.5 PyMySQL==1.1.0 ``` 安装命令: ```bash pip install -r requirements.txt ``` 启动后端: ```bash python app.py ``` 访问:`http://localhost:5000/api/students` 应返回空列表。 --- ## 🌐 第三步:Vue3 + Element Plus 前端实现 ### 创建 Vue 项目(使用 Vite) ```bash cd frontend npm create vue@latest # 选择 Vue Router, Pinia 可选,CSS 预处理器等 npm install ``` 然后安装 Element Plus 和 Axios: ```bash npm install element-plus axios npm install --save-dev @element-plus/icons-vue ``` --- ### `frontend/src/main.js` ```js import { createApp } from 'vue' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import '@element-plus/icons-vue' const app = createApp(App) app.use(router) app.use(ElementPlus) app.mount('#app') ``` --- ### `frontend/src/views/StudentList.vue` ```vue <template> <div class="p-6"> <h2 class="text-2xl font-bold mb-4">学生信息管理</h2> <!-- 搜索与新增 --> <div class="flex justify-between mb-4"> <el-input v-model="keyword" placeholder="请输入姓名或学号" style="width: 300px;" @input="search" /> <el-button type="primary" @click="openAddDialog">新增学生</el-button> </div> <!-- 表格 --> <el-table :data="tableData" stripe style="width: 100%" v-loading="loading"> <el-table-column prop="student_id" label="学号" width="120" /> <el-table-column prop="name" label="姓名" width="100" /> <el-table-column prop="gender" label="性别" width="80" /> <el-table-column prop="age" label="年龄" width="80" /> <el-table-column prop="phone" label="电话" width="120" /> <el-table-column prop="email" label="邮箱" /> <el-table-column label="操作" width="180"> <template #default="scope"> <el-button size="small" @click="editStudent(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="deleteStudent(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <div class="mt-4 flex justify-end"> <el-pagination @current-change="handlePageChange" :current-page="currentPage" :page-size="pageSize" :total="total" layout="total, prev, pager, next" /> </div> <!-- 弹窗表单 --> <el-dialog :title="dialogTitle" v-model="dialogVisible"> <el-form :model="form" :rules="rules" ref="formRef"> <el-form-item label="学号" prop="student_id"> <el-input v-model="form.student_id" :disabled="!!form.id" /> </el-form-item> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item label="性别" prop="gender"> <el-radio-group v-model="form.gender"> <el-radio label="男">男</el-radio> <el-radio label="女">女</el-radio> </el-radio-group> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input-number v-model="form.age" :min="1" :max="150" /> </el-form-item> <el-form-item label="电话" prop="phone"> <el-input v-model="form.phone" /> </el-form-item> <el-form-item label="邮箱" prop="email"> <el-input v-model="form.email" /> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </span> </template> </el-dialog> </div> </template> <script setup> import { ref, reactive, onMounted } from 'vue' import axios from 'axios' const tableData = ref([]) const total = ref(0) const currentPage = ref(1) const pageSize = ref(10) const keyword = ref('') const loading = ref(false) // 表单相关 const dialogVisible = ref(false) const formRef = ref(null) const isEdit = ref(false) const form = reactive({ id: null, student_id: '', name: '', gender: '男', age: 18, phone: '', email: '' }) const rules = { student_id: [{ required: true, message: '请输入学号', trigger: 'blur' }], name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], age: [{ required: true, message: '请输入年龄', trigger: 'blur' }] } // 获取数据 const fetchData = () => { loading.value = true axios.get('/api/students', { params: { page: currentPage.value, limit: pageSize.value, keyword: keyword.value } }).then(res => { const data = res.data if (data.success) { tableData.value = data.data total.value = data.total } }).finally(() => { loading.value = false }) } // 分页变化 const handlePageChange = (page) => { currentPage.value = page fetchData() } // 搜索 const search = () => { currentPage.value = 1 fetchData() } // 打开新增弹窗 const openAddDialog = () => { isEdit.value = false dialogVisible.value = true nextTick(() => { formRef.value?.resetFields() Object.assign(form, { id: null, student_id: '', name: '', gender: '男', age: 18, phone: '', email: '' }) }) } // 编辑 const editStudent = (row) => { isEdit.value = true dialogVisible.value = true nextTick(() => { formRef.value?.resetFields() Object.assign(form, row) }) } // 提交表单 const submitForm = () => { formRef.value.validate(valid => { if (!valid) return const method = isEdit.value ? 'put' : 'post' const url = isEdit.value ? `/api/students/${form.id}` : '/api/students' axios[method](url, form).then(res => { if (res.data.success) { ElMessage.success(res.data.message) dialogVisible.value = false fetchData() } else { ElMessage.error(res.data.message) } }) }) } // 删除 const deleteStudent = (id) => { ElMessageBox.confirm('确定删除该学生?', '警告', { type: 'warning' }).then(() => { axios.delete(`/api/students/${id}`).then(res => { if (res.data.success) { ElMessage.success('删除成功') fetchData() } else { ElMessage.error(res.data.message) } }) }) } onMounted(() => { fetchData() }) </script> <style scoped> .dialog-footer button:first-child { margin-right: 10px; } </style> ``` --- ### 配置代理(解决跨域) 修改 `vite.config.js` ```js export default defineConfig({ plugins: [...], server: { proxy: { '/api': { target: 'http://localhost:5000', changeOrigin: true } } } }) ``` --- ## ▶️ 启动方式 1. 启动后端Flask): ```bash cd backend python app.py ``` 2. 启动前端Vue): ```bash cd frontend npm run dev ``` 3. 访问:`http://localhost:5173` --- ## ✅ 效果展示 - 显示学生列表(带分页) - 支持模糊搜索 - 可新增、编辑、删除 - 使用 Element Plus 提供现代化 UI --- ## 🔐 安全建议(进阶) - 添加 JWT 身份验证 - 参数校验增强 - SQL 注入防护(已由 SQLAlchemy 天然防止) - 前端输入 XSS 过滤 - 日志记录操作行为 --- ## 📦 打包部署建议 - 后端:使用 Gunicorn + Nginx 部署 Flask - 前端:`npm run build` 生成静态文件,由 Nginx 托管 - 数据库:生产环境使用连接池(如 SQLAlchemy + gevent) ---
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值