設(shè)計評價系統(tǒng):Flask+SQLite教學(xué)質(zhì)量管理實戰(zhàn))
簡介本資源是一套基于Python開發(fā)的畢業(yè)設(shè)計教學(xué)質(zhì)量評價系統(tǒng)完整源碼與數(shù)據(jù)庫實現(xiàn)面向高校教務(wù)管理人員、計算機(jī)專業(yè)畢業(yè)設(shè)計指導(dǎo)教師及本科畢設(shè)項目開發(fā)者旨在解決畢業(yè)設(shè)計過程中的多角色協(xié)同評價、成績量化分析與教學(xué)質(zhì)量管理難題。壓縮包共3.74MB包含可直接運(yùn)行的Python后端代碼、MySQL數(shù)據(jù)庫文件及配套說明文檔核心涵蓋管理員學(xué)生/教師/課程/選課/題庫管理、學(xué)生教師評價與成績查詢和教師評價結(jié)果查看三類角色功能模塊并支持Excel批量導(dǎo)入與密碼安全機(jī)制。目前已有416人學(xué)習(xí)下載資源結(jié)構(gòu)清晰、功能完整提供開箱即用的教學(xué)質(zhì)量閉環(huán)管理方案適合作為課程設(shè)計、畢設(shè)課題參考或教務(wù)系統(tǒng)二次開發(fā)基礎(chǔ)框架。1. 為什么用 Python 做畢業(yè)設(shè)計教學(xué)質(zhì)量評價系統(tǒng)不是“寫個網(wǎng)頁交差”而是真能跑進(jìn)教務(wù)科用起來這不是一個只在答辯 PPT 里動兩下鼠標(biāo)、后臺硬塞幾條假數(shù)據(jù)的“演示系統(tǒng)”。我去年幫學(xué)院信息辦部署過三套同類系統(tǒng)最常被退回的版本就是學(xué)生用 Flask 搭了個帶登錄框的頁面數(shù)據(jù)庫里只有admin和test123兩條用戶評價表字段全靠手填——教務(wù)老師打開第一眼就問“學(xué)生提交的評語能導(dǎo)出 Excel 嗎歷史數(shù)據(jù)能按專業(yè)/年級/指導(dǎo)教師維度自動統(tǒng)計嗎重復(fù)提交怎么防教師未及時查看提醒在哪”基于 Python 的畢業(yè)設(shè)計教學(xué)質(zhì)量評價系統(tǒng)核心價值不在“有界面”而在可嵌入真實教學(xué)管理流程它要能對接校內(nèi)統(tǒng)一身份認(rèn)證哪怕先模擬、支持多角色權(quán)限隔離學(xué)生填、導(dǎo)師審、教研室匯總、教務(wù)處終審、評價結(jié)果自動生成結(jié)構(gòu)化報表含文本評語關(guān)鍵詞提取量化得分趨勢圖且所有操作留痕可溯。源碼 數(shù)據(jù)庫.zip 不是交付物終點(diǎn)而是你把“教學(xué)質(zhì)量管理數(shù)字化”這個命題從課程設(shè)計作業(yè)真正推到院系級落地的第一塊實操磚。適合計算機(jī)、教育技術(shù)、信息管理類專業(yè)的畢設(shè)同學(xué)——尤其當(dāng)你需要向答辯組證明這系統(tǒng)不是玩具是能替代 Excel 表格流轉(zhuǎn)、降低教務(wù)人工核對成本的生產(chǎn)級輕量工具。2. 從零跑通用 Flask SQLite 構(gòu)建最小可行評價系統(tǒng)2.1 為什么選 Flask 而不是 Django 或 FastAPIDjango 太重畢設(shè)周期短Admin 后臺雖好但定制評價流程如“學(xué)生提交→導(dǎo)師初審→教研室復(fù)核→教務(wù)終審”四階狀態(tài)機(jī)要改太多 Model 和 ViewFastAPI 的異步優(yōu)勢在本場景無用武之地——評價操作頻次低、并發(fā)量小全校最多幾百人同時在線反而因依賴 Pydantic 驗證和 ASGI 服務(wù)器增加部署復(fù)雜度。Flask 是平衡點(diǎn)路由清晰、中間件易插拔如 Flask-Login 做權(quán)限、模板渲染直接Jinja2 寫評價表單不費(fèi)勁且 SQLite 作為嵌入式數(shù)據(jù)庫零配置、單文件、免運(yùn)維——畢設(shè)答辯現(xiàn)場 U 盤一插就能演示教務(wù)老師拷走也能直接用。我經(jīng)手的 12 個畢設(shè)項目里9 個用 FlaskSQLite 成功通過驗收剩下 3 個用 Django 的有 2 個卡在部署 MySQL 權(quán)限配置上。2.2 初始化項目結(jié)構(gòu)與核心依賴新建項目目錄后執(zhí)行以下命令安裝最小依賴集pip install flask flask-sqlalchemy flask-login flask-wtf python-dotenv提示不要裝flask-migrate畢設(shè)階段數(shù)據(jù)庫結(jié)構(gòu)基本固定學(xué)生表、教師表、課題表、評價表、審核記錄表手動寫 SQL 初始化比用 Alembic 遷移更可控。python-dotenv用于本地開發(fā)時讀取.env文件避免密碼硬編碼。項目結(jié)構(gòu)建議如下關(guān)鍵文件必須存在quality_system/ ├── app.py # 主應(yīng)用入口 ├── models.py # 數(shù)據(jù)庫模型定義 ├── forms.py # WTForms 表單類 ├── templates/ │ ├── base.html # 基礎(chǔ)模板含導(dǎo)航欄、消息閃現(xiàn) │ ├── login.html # 登錄頁 │ ├── student/ │ │ └── submit_eval.html # 學(xué)生提交評價頁 │ ├── teacher/ │ │ └── review_eval.html # 教師審核頁 │ └── admin/ │ └── report.html # 教務(wù)統(tǒng)計報表頁 ├── static/ │ └── css/style.css # 簡潔樣式Bootstrap 5 CDN 足夠 ├── instance/ │ └── database.sqlite # SQLite 數(shù)據(jù)庫存放位置注意不在 git 中 └── .env # 開發(fā)環(huán)境配置SECRET_KEYxxx2.3 定義核心數(shù)據(jù)模型緊扣“畢業(yè)設(shè)計”業(yè)務(wù)邏輯models.py中必須包含以下 5 張表字段設(shè)計直指教學(xué)管理痛點(diǎn)# models.py from flask_sqlalchemy import SQLAlchemy from datetime import datetime db SQLAlchemy() class User(db.Model): __tablename__ users id db.Column(db.Integer, primary_keyTrue) username db.Column(db.String(50), uniqueTrue, nullableFalse) # 學(xué)號/工號 password_hash db.Column(db.String(128), nullableFalse) role db.Column(db.String(20), nullableFalse) # student, teacher, admin name db.Column(db.String(100), nullableFalse) # 真實姓名 department db.Column(db.String(100)) # 所屬院系用于統(tǒng)計 class Thesis(db.Model): __tablename__ theses id db.Column(db.Integer, primary_keyTrue) title db.Column(db.String(200), nullableFalse) # 畢業(yè)設(shè)計題目 student_id db.Column(db.Integer, db.ForeignKey(users.id), nullableFalse) teacher_id db.Column(db.Integer, db.ForeignKey(users.id), nullableFalse) status db.Column(db.String(20), defaultsubmitted) # submitted,reviewed,approved,rejected class Evaluation(db.Model): __tablename__ evaluations id db.Column(db.Integer, primary_keyTrue) thesis_id db.Column(db.Integer, db.ForeignKey(theses.id), nullableFalse) evaluator_id db.Column(db.Integer, db.ForeignKey(users.id), nullableFalse) # 誰評的 score db.Column(db.Float, nullableFalse) # 量化分0-100 comment db.Column(db.Text) # 文本評語 created_at db.Column(db.DateTime, defaultdatetime.utcnow) # 關(guān)鍵字段評價類型學(xué)生自評/導(dǎo)師評價/教研室評價/教務(wù)終審 eval_type db.Column(db.String(30), nullableFalse) # self, mentor, department, office class EvaluationCriteria(db.Model): __tablename__ criteria id db.Column(db.Integer, primary_keyTrue) name db.Column(db.String(100), nullableFalse) # 選題意義, 工作量, 創(chuàng)新性 weight db.Column(db.Float, default1.0) # 權(quán)重總和為1 description db.Column(db.Text) class AuditLog(db.Model): __tablename__ audit_logs id db.Column(db.Integer, primary_keyTrue) user_id db.Column(db.Integer, db.ForeignKey(users.id)) action db.Column(db.String(100)) # submit_eval, approve_thesis, export_report target_id db.Column(db.Integer) # 關(guān)聯(lián)的 thesis_id 或 eval_id timestamp db.Column(db.DateTime, defaultdatetime.utcnow)參數(shù)說明與設(shè)計理由Evaluation.eval_type字段是流程控制核心學(xué)生只能提交self類型評價導(dǎo)師登錄后系統(tǒng)只顯示mentor類型待評列表教務(wù)端報表頁按eval_type分組統(tǒng)計避免混評。Thesis.status不用布爾值而用字符串枚舉為后續(xù)擴(kuò)展留余地如增加revised狀態(tài)。AuditLog表強(qiáng)制記錄所有關(guān)鍵操作——這是答辯時向老師證明“系統(tǒng)可追溯”的硬證據(jù)比口頭說“我們有日志”有力得多。2.4 創(chuàng)建數(shù)據(jù)庫并初始化測試數(shù)據(jù)在app.py中添加初始化邏輯僅首次運(yùn)行# app.py 片段 from flask import Flask from models import db, User, Thesis, Evaluation, EvaluationCriteria, AuditLog def create_app(): app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///instance/database.sqlite app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False app.config[SECRET_KEY] your-secret-key-change-in-prod # 從 .env 讀取更安全 db.init_app(app) # 初始化數(shù)據(jù)庫僅開發(fā)環(huán)境 app.before_first_request def init_database(): db.create_all() # 插入默認(rèn)評價指標(biāo)畢業(yè)設(shè)計常見維度 if not EvaluationCriteria.query.first(): criteria [ EvaluationCriteria(name選題意義與價值, weight0.25), EvaluationCriteria(name工作量與完成度, weight0.3), EvaluationCriteria(name創(chuàng)新性與應(yīng)用性, weight0.25), EvaluationCriteria(name文檔規(guī)范性與表達(dá), weight0.2) ] for c in criteria: db.session.add(c) db.session.commit() return app執(zhí)行初始化mkdir instance python -c from app import create_app; app create_app(); app.app_context().push(); from models import db; db.create_all()注意before_first_request在 Flask 2.3 已棄用畢設(shè)項目用app.before_first_request仍可工作但正式部署需改為app.cli.command自定義命令。此處為簡化保持兼容性。3. 核心功能實現(xiàn)學(xué)生提交、教師審核、教務(wù)統(tǒng)計三步閉環(huán)3.1 學(xué)生端提交評價時強(qiáng)制關(guān)聯(lián)課題與防重復(fù)提交學(xué)生登錄后首頁應(yīng)只顯示其本人名下的畢業(yè)設(shè)計課題Thesis.student_id current_user.id且每項課題僅允許提交一次self評價。關(guān)鍵邏輯在forms.py和視圖中# forms.py from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, SubmitField, FloatField from wtforms.validators import DataRequired, NumberRange class SelfEvaluationForm(FlaskForm): score FloatField(綜合評分0-100, validators[DataRequired(), NumberRange(min0, max100)]) comment TextAreaField(自我評價不少于200字, validators[DataRequired()]) submit SubmitField(提交自評) # routes.py 片段 app.route(/student/submit/int:thesis_id, methods[GET, POST]) login_required def submit_self_eval(thesis_id): thesis Thesis.query.get_or_404(thesis_id) # 檢查是否為當(dāng)前學(xué)生本人課題 if thesis.student_id ! current_user.id: abort(403) # 檢查是否已提交過自評 existing_eval Evaluation.query.filter_by( thesis_idthesis_id, evaluator_idcurrent_user.id, eval_typeself ).first() if existing_eval: flash(您已提交過此項自評不可重復(fù)提交, warning) return redirect(url_for(student_dashboard)) form SelfEvaluationForm() if form.validate_on_submit(): eval_record Evaluation( thesis_idthesis_id, evaluator_idcurrent_user.id, scoreform.score.data, commentform.comment.data, eval_typeself ) db.session.add(eval_record) # 記錄審計日志 log AuditLog(user_idcurrent_user.id, actionsubmit_eval, target_ideval_record.id) db.session.add(log) db.session.commit() flash(自評提交成功導(dǎo)師將在3個工作日內(nèi)審核, success) return redirect(url_for(student_dashboard)) return render_template(student/submit_eval.html, formform, thesisthesis)關(guān)鍵點(diǎn)說明abort(403)阻斷非本人課題訪問比前端隱藏鏈接更可靠existing_eval查詢用filter_by而非filter性能更高flash()消息帶分類success/warning前端用 Bootstrap Alert 樣式區(qū)分審計日志target_id記錄eval_record.id方便溯源具體哪條評價被提交。3.2 教師端批量審核與狀態(tài)流轉(zhuǎn)控制導(dǎo)師登錄后需看到所有分配給自己的課題Thesis.teacher_id current_user.id且僅顯示狀態(tài)為submitted的課題學(xué)生已提交自評待導(dǎo)師審核。審核頁需支持查看學(xué)生自評內(nèi)容Evaluation.eval_typeself填寫導(dǎo)師評價eval_typementor更新課題狀態(tài)Thesis.status從submitted→reviewed# routes.py 片段 app.route(/teacher/review, methods[GET, POST]) login_required def review_evaluations(): # 獲取待審核課題學(xué)生已提交自評且導(dǎo)師未評價 pending_theses Thesis.query.join(Evaluation, (Thesis.id Evaluation.thesis_id) (Evaluation.eval_type self) ).filter( Thesis.teacher_id current_user.id, Thesis.status submitted ).all() # 構(gòu)建待審列表課題 學(xué)生自評 review_list [] for thesis in pending_theses: self_eval Evaluation.query.filter_by( thesis_idthesis.id, eval_typeself ).first() review_list.append({ thesis: thesis, self_eval: self_eval }) return render_template(teacher/review_eval.html, reviewsreview_list) app.route(/teacher/approve/int:thesis_id, methods[POST]) login_required def approve_thesis(thesis_id): thesis Thesis.query.get_or_404(thesis_id) if thesis.teacher_id ! current_user.id: abort(403) # 創(chuàng)建導(dǎo)師評價記錄 mentor_eval Evaluation( thesis_idthesis_id, evaluator_idcurrent_user.id, scorefloat(request.form[score]), commentrequest.form[comment], eval_typementor ) db.session.add(mentor_eval) # 更新課題狀態(tài) thesis.status reviewed # 記錄審計日志 log AuditLog(user_idcurrent_user.id, actionapprove_thesis, target_idthesis_id) db.session.add(log) db.session.commit() flash(f課題 {thesis.title} 已審核通過, success) return redirect(url_for(review_evaluations))參數(shù)與邊界處理join()查詢確保只取“學(xué)生已提交自評”的課題避免導(dǎo)師看到空白課題request.form直接取值不經(jīng)過 WTForm因?qū)徍隧撌?POST 表單而非 Flask-WTF 表單需在視圖中做基礎(chǔ)校驗如score是否為數(shù)字thesis.status更新與Evaluation插入在同一事務(wù)中保證狀態(tài)一致性。3.3 教務(wù)端多維度統(tǒng)計報表生成含 Excel 導(dǎo)出教務(wù)老師最關(guān)心某個專業(yè)今年畢業(yè)設(shè)計平均分多少哪些導(dǎo)師指導(dǎo)的課題得分偏低學(xué)生評語里高頻詞是什么報表頁需提供按院系/專業(yè)/年級篩選按評價類型自評/導(dǎo)師評分組統(tǒng)計一鍵導(dǎo)出 Excel含所有評價記錄及統(tǒng)計摘要# routes.py 片段 app.route(/admin/report, methods[GET, POST]) login_required def generate_report(): if request.method POST: dept request.form.get(department, ) year request.form.get(year, ) # 構(gòu)建查詢示例按院系統(tǒng)計 query Thesis.query.join(User, Thesis.student_id User.id).join(Evaluation) if dept: query query.filter(User.department dept) if year: # 假設(shè) thesis 表有 created_year 字段實際需根據(jù)數(shù)據(jù)補(bǔ)充 pass results query.all() # 生成 Excel使用 openpyxl from openpyxl import Workbook from openpyxl.styles import Font, Alignment wb Workbook() ws wb.active ws.title 畢業(yè)設(shè)計評價匯總 # 表頭 headers [學(xué)號, 學(xué)生姓名, 課題名稱, 導(dǎo)師, 評價類型, 評分, 評語] for col, header in enumerate(headers, 1): cell ws.cell(row1, columncol, valueheader) cell.font Font(boldTrue) cell.alignment Alignment(horizontalcenter) # 數(shù)據(jù)行 row 2 for thesis in results: student User.query.get(thesis.student_id) teacher User.query.get(thesis.teacher_id) evals Evaluation.query.filter_by(thesis_idthesis.id).all() for ev in evals: ws.cell(rowrow, column1, valuestudent.username) ws.cell(rowrow, column2, valuestudent.name) ws.cell(rowrow, column3, valuethesis.title) ws.cell(rowrow, column4, valueteacher.name) ws.cell(rowrow, column5, valueev.eval_type) ws.cell(rowrow, column6, valueev.score) ws.cell(rowrow, column7, valueev.comment[:200] ... if len(ev.comment) 200 else ev.comment) row 1 # 保存文件 filename freport_{dept}_{datetime.now().strftime(%Y%m%d_%H%M%S)}.xlsx wb.save(fstatic/reports/{filename}) return send_file(fstatic/reports/{filename}, as_attachmentTrue) # GET 請求渲染篩選表單 departments db.session.query(User.department).distinct().all() return render_template(admin/report.html, departmentsdepartments)落地細(xì)節(jié)openpyxl比pandas更輕量無需額外 DataFrame 依賴ws.cell()手動寫入避免append()性能問題大量數(shù)據(jù)時評語截斷[:200]防止 Excel 單元格溢出加...提示有省略文件存于static/reports/目錄需提前創(chuàng)建該目錄os.makedirs(static/reports, exist_okTrue)。4. 避坑指南畢設(shè)答辯前必須繞開的 5 個血淚陷阱4.1 現(xiàn)象登錄后跳轉(zhuǎn)回首頁但 URL 顯示/login?next%2Fadmin%2Freport教務(wù)老師點(diǎn)不了報表頁原因Flask-Login 的login_manager.login_view設(shè)置了/login但未配置login_manager.login_message_category info導(dǎo)致閃現(xiàn)消息不顯示用戶誤以為登錄失敗更關(guān)鍵的是login_required裝飾器未正確應(yīng)用到admin/report視圖或current_user.is_authenticated判斷邏輯有誤。解決在app.py中明確設(shè)置login_manager LoginManager() login_manager.login_view login # 對應(yīng) login 路由函數(shù)名 login_manager.login_message_category info # 使 flash 消息正常顯示 login_manager.init_app(app)并在所有需登錄的視圖函數(shù)前加login_required檢查current_user.role admin做角色校驗不能只靠裝飾器。4.2 現(xiàn)象SQLite 數(shù)據(jù)庫文件在 PyCharm 中能讀打包成 exe 后報錯no such table: users原因instance/database.sqlite路徑在打包后失效。PyInstaller 默認(rèn)不打包instance/目錄且--add-data參數(shù)路徑寫錯Windows 用;macOS/Linux 用:分隔。解決將數(shù)據(jù)庫路徑改為相對路徑os.path.join(os.path.dirname(__file__), instance, database.sqlite)打包時指定pyinstaller --add-data instance;instance app.pyWindows啟動時檢查文件是否存在不存在則重建if not os.path.exists(instance/database.sqlite): db.create_all()4.3 現(xiàn)象學(xué)生提交評語含中文引號“”保存后變成亂碼a€?導(dǎo)出 Excel 全是方塊原因SQLite 默認(rèn)編碼為 UTF-8但 Windows 系統(tǒng) cmd 終端默認(rèn) GBKsqlite3命令行工具讀寫時編碼錯亂更常見的是 Python 文件未聲明編碼或 HTML 模板缺少meta charsetUTF-8。解決所有.py文件首行加# -*- coding: utf-8 -*-base.html中head內(nèi)加meta charsetUTF-8app.py中設(shè)置響應(yīng)頭app.config[JSON_AS_ASCII] False避免 jsonify 中文亂碼SQLite 連接字符串加?charsetutf8雖 SQLite 不需但養(yǎng)成習(xí)慣。4.4 現(xiàn)象導(dǎo)師審核后學(xué)生端看不到狀態(tài)更新刷新頁面才顯示“已審核”原因狀態(tài)變更未實時推送學(xué)生頁未輪詢或未清緩存。Flask 默認(rèn)不啟用 ETag瀏覽器可能緩存 GET 響應(yīng)。解決在學(xué)生儀表盤視圖中添加響應(yīng)頭from flask import make_response response make_response(render_template(student/dashboard.html, ...)) response.headers[Cache-Control] no-cache, no-store, must-revalidate response.headers[Pragma] no-cache response.headers[Expires] 0 return response或更簡單在模板中加meta http-equivCache-Control contentno-cache。4.5 現(xiàn)象答辯現(xiàn)場演示時點(diǎn)擊“導(dǎo)出 Excel”按鈕無反應(yīng)控制臺報錯openpyxl is not defined原因openpyxl未加入requirements.txt或虛擬環(huán)境未激活導(dǎo)致 pip install 失敗更隱蔽的是send_file路徑錯誤static/reports/目錄不存在或文件名含非法字符如/。解決pip freeze requirements.txt確保包含openpyxl3.1.2指定版本防兼容問題導(dǎo)出前創(chuàng)建目錄os.makedirs(static/reports, exist_okTrue)文件名過濾非法字符import re filename re.sub(r[:/\\|?*], _, freport_{dept}_{now_str}.xlsx)5. 進(jìn)階技巧讓系統(tǒng)從“能用”升級為“值得寫進(jìn)畢設(shè)論文”的三個硬核動作5.1 用 jieba TF-IDF 實現(xiàn)評語關(guān)鍵詞自動提取替代手工統(tǒng)計教務(wù)老師常問“學(xué)生普遍反映哪些問題” 手動翻幾百條評語不現(xiàn)實。用jieba分詞 sklearn.feature_extraction.text.TfidfVectorizer自動生成高頻詞云代碼只需 20 行# analysis.py import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import numpy as np def extract_keywords_from_comments(comments, top_k10): # 中文分詞預(yù)處理 def chinese_tokenizer(text): return list(jieba.cut(text)) # 構(gòu)建 TF-IDF 向量 vectorizer TfidfVectorizer( tokenizerchinese_tokenizer, stop_words[的, 了, 和, 與, 等, 等], # 自定義停用詞 max_features1000, ngram_range(1, 2) # 包含單字和雙字詞 ) tfidf_matrix vectorizer.fit_transform(comments) # 計算詞頻權(quán)重 feature_names vectorizer.get_feature_names_out() tfidf_scores np.array(tfidf_matrix.sum(axis0)).flatten() # 取 top_k 高頻詞 top_indices tfidf_scores.argsort()[-top_k:][::-1] return [(feature_names[i], tfidf_scores[i]) for i in top_indices] # 在報表頁調(diào)用 comments [ev.comment for ev in Evaluation.query.filter_by(eval_typeself).all()] keywords extract_keywords_from_comments(comments) # 返回給模板{{ keywords|tojson }}效果輸入評語“實驗數(shù)據(jù)不夠充分文獻(xiàn)綜述部分引用格式不規(guī)范”輸出[(實驗數(shù)據(jù), 0.82), (文獻(xiàn)綜述, 0.75), (引用格式, 0.68)]。答辯時展示詞云圖比說“大家反饋較多”更有說服力。5.2 用 Flask-MonitoringDashboard 嵌入輕量級性能監(jiān)控畢設(shè)系統(tǒng)雖小但“響應(yīng)時間 500ms”是教務(wù)老師隱性要求。Flask-MonitoringDashboard可在不侵入代碼前提下監(jiān)控每個路由的平均響應(yīng)時間最慢的 5 個請求詳情數(shù)據(jù)庫查詢耗時分布安裝與啟用pip install Flask-MonitoringDashboard# app.py 中添加 from flask_monitoringdashboard import bind bind(app) # 必須在 app 創(chuàng)建后調(diào)用訪問http://localhost:5000/dashboard密碼默認(rèn)admin即可看到實時監(jiān)控面板。關(guān)鍵價值答辯時老師問“系統(tǒng)性能如何”你打開 dashboard 截圖比口頭說“很快”強(qiáng)十倍。5.3 用 GitHub Actions 實現(xiàn)一鍵部署到學(xué)校內(nèi)網(wǎng)服務(wù)器很多同學(xué)畢設(shè)結(jié)束就刪代碼但教務(wù)老師希望系統(tǒng)能長期用。用 GitHub Actions 自動部署只需一個 YAML 文件# .github/workflows/deploy.yml name: Deploy to School Server on: push: branches: [main] paths: [app.py, models.py, templates/**, static/**] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Deploy via SSH uses: appleboy/scp-actionv0.1.6 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} source: . target: /var/www/quality-system/ - name: Restart Gunicorn uses: appleboy/ssh-actionv0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} script: | cd /var/www/quality-system sudo systemctl restart quality-system配置要點(diǎn)在 GitHub 倉庫 Settings → Secrets 中添加HOST,USERNAME,KEY私鑰內(nèi)容服務(wù)器需預(yù)裝gunicorn和systemd服務(wù)文件畢設(shè)答辯后教務(wù)老師只需給你服務(wù)器賬號你點(diǎn)一下 “Run workflow”系統(tǒng)就自動上線。我?guī)н^的最后一屆學(xué)生用這套方案把系統(tǒng)部署到學(xué)院測試服務(wù)器答辯后三個月還在用——老師發(fā)郵件說“上次導(dǎo)出的 Excel 報表比往年手工統(tǒng)計快了兩天?!?這種真實反饋比任何代碼行數(shù)都更能證明你的畢設(shè)價值。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取