Flask毕业设计实战:任务清单管理系统从项目结构到测试部署
简介面向毕业设计与课程设计场景的PythonFlask任务清单管理系统后端使用Flask框架前端可结合Vue实现任务看板交互是一套完整可运行的ToDoList案例。系统代码涵盖用户认证、任务增删改查、数据持久化等核心模块并附带自动化测试脚本能够帮助初学者快速理解Flask项目结构、REST路由和前后端对接思路。项目代码划分清晰配置、启动、测试相互独立便于模块化维护。资源包共21个文件以12个Python源文件为主另有SQLite数据库、依赖清单、pyc缓存文件与文本说明压缩包整体仅15KB目录紧凑清晰便于直接阅读和二次开发。目前已有90人学习浏览该毕业设计项目经验证可在Windows10/11环境下稳定运行答辩评审成绩97分配有基础部署说明下载即可运行适合用于毕业设计参考、课程设计演示也可作为Flask实战练手的优质范例。1. 让Flask毕业设计不再只有增删改查一个能答辩的任务清单管理项目很多准备做Flask毕业设计的人最后交上去的往往是一个路由全堆在app.py里的增删改查demo。这个基于PythonFlask的任务清单管理源码不一样它把应用工厂、Blueprint、认证模块、pytest测试目录和配置分离全部组织好了答辩时你能顺着“为什么这么分层”讲出一条完整逻辑线而不是被评委追问“代码是不是抄的”。项目在Window10/11下反复调试过解压后按使用文档操作即可运行自带>from flask import Flask from config import Config def create_app(config_classConfig): app Flask(__name__) app.config.from_object(config_class) from app.auth import bp as auth_bp app.register_blueprint(auth_bp, url_prefix/auth) from app.todo import bp as todo_bp app.register_blueprint(todo_bp) return appcreate_app在函数内部创建Flask实例并注册蓝图这样做的好处是可以多次调用。测试时传入不同的配置类即可生产环境切换到MySQL时也不需要修改蓝图代码。url_prefix/auth把登录注册相关的路由统一挂到/auth前缀下视图函数内部的url_for(auth.login)需要带上蓝图名这是Blueprint路由命名空间最基本的使用规范。2.3 config.py 里的环境分离是怎么实现的再看config.py它通常定义了一个基类并用子类区分环境import os basedir os.path.abspath(os.path.dirname(__file__)) class Config: SECRET_KEY os.environ.get(SECRET_KEY) or dev-key-change-me SQLALCHEMY_DATABASE_URI sqlite:/// os.path.join(basedir, todo.db) SQLALCHEMY_TRACK_MODIFICATIONS False class TestConfig(Config): TESTING True SQLALCHEMY_DATABASE_URI sqlite:/// os.path.join(basedir, data-test.sqlite)SECRET_KEY是Flask处理session的必要配置不配置的话登录功能会直接报错。TestConfig单独指定>from werkzeug.security import generate_password_hash, check_password_hash from flask import session, redirect, url_for, flash, request from functools import wraps def login_required(view): wraps(view) def wrapped(**kwargs): if user_id not in session: flash(请先登录) return redirect(url_for(auth.login)) return view(**kwargs) return wrapped bp.route(/register, methods[GET, POST]) def register(): if request.method POST: username request.form[username] password request.form[password] # 实际项目里应检查用户名唯一性然后再写入数据库 hashed generate_password_hash(password) # db.session.add(User(usernameusername, password_hashhashed)) # db.session.commit() return redirect(url_for(auth.login))login_required是装饰器functools.wraps保证了被装饰函数的元信息不被覆盖。generate_password_hash默认使用pbkdf2算法带随机盐注册时存哈希值登录时用check_password_hash(hashed, password)验证。评委大概率会问“密码怎么保护”这条要答出来。3.2 任务添加、完成与删除状态流转设计任务清单的核心是任务状态的管理。常见设计是Task模型包含id、user_id、title、done、created_at五个字段done用布尔值表示。添加任务的视图代码bp.route(/add, methods[POST]) login_required def add_task(): title request.form.get(title, ).strip() if not title: flash(任务内容不能为空) return redirect(url_for(todo.index)) # current_user 通常由 Flask-Login 提供也可从 session 取值 # task Task(titletitle, user_idsession[user_id]) # db.session.add(task) # db.session.commit() flash(任务已添加) return redirect(url_for(todo.index))这个案例里“完成状态切换”走的是单独的POST请求而不是用GET改数据。模板中每个未完成任务会渲染一个表单表单里的隐藏字段存任务id按钮提交到/toggle/task_id。这样做的好处是浏览器刷新时不会重复提交符合HTML语义也方便后续在演示时解释REST风格与表单提交的区别。3.3 SQLite数据文件与表结构验证>sqlite3>def test_index_redirects_to_login(client): response client.get(/) assert response.status_code 302 def test_login_page_renders(client): response client.get(/auth/login) assert response.status_code 200 assert 用户名 in response.get_data(as_textTrue)client是 pytest 的 fixture通常定义在conftest.py中它会创建一个测试专用的Flask应用并交出测试客户端。status_code 302说明未登录用户访问首页会被重定向到登录页这就是上一章login_required装饰器在起效。test_number.py则偏重统计逻辑常见做法是注册用户后检查任务数量是否与预期一致。4.2 conftest与测试数据库的配合方式测试相关配置由TestConfig提供它把数据库指向>import pytest from app import create_app from config import TestConfig pytest.fixture() def app(): app create_app(TestConfig) with app.app_context(): # 建表语句放这里 pass yield app pytest.fixture() def client(app): return app.test_client()注意yield之前的代码在测试开始时执行yield之后的代码在测试结束时执行。在app_context里建表是为了保证db.create_all()能在正确的应用上下文中运行脱离上下文直接操作表会抛出RuntimeError。测试运行命令是pytest -v-v参数会打印每个测试函数的通过状态。如果输出乱码通常是在Windows终端下没有设置UTF-8编码可以在运行前执行set PYTHONIOENCODINGutf-8。4.3 测试数据隔离与常见失败原因跑测试时最容易出现两类失败一是 session 污染登录测试中 cookie 跨用例传递导致依赖顺序二是测试库文件残留旧数据让断言数量不准确。解决办法不是去改断言而是每次测试前重建表。SQLite 的优点是重建成本低直接在 fixture 里加两行删除建表即可。如果出现sqlite3.OperationalError: no such table基本都是测试上下文没进app_context和上面说的RuntimeError是同一个问题。5. 部署与答辩演示Windows10/11下快速跑通接口与验收清单5.1 环境准备与依赖安装的完整命令序列项目在Windows10/11环境调试通过但前提是Python环境已装好。建议使用Python 3.7或3.8版本过高的Python版本可能因为依赖包未跟上而编译报错。进入项目根目录后依次执行python -m venv venv venv\Scripts\activate pip install -r requirements.txt第一条命令创建虚拟环境第二条激活第三条按requirements.txt安装所有依赖。因为requirements.txt锁定了Flask等库的版本号后续在任何机器上复现时依赖版本都一致避免“我机器上能跑你机器上跑不了”的尴尬。如果下载特别慢可临时换国内镜像pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple。在PyCharm或VS Code里打开项目时解释器要选择venv目录下的PythonIDE终端是否能识别flask命令取决于虚拟环境是否激活。5.2 初始化数据库并启动服务启动前先看manage.py提供了哪些命令。常见写法是用Flask-Script风格的Manager命令初始化后启动python manage.py init-db python manage.py runserver如果项目用的是Flask 2.x也可以直接走flask命令行set FLASK_APPapp.py set FLASK_DEBUG1 flask init-db flask run --host127.0.0.1 --port5000FLASK_APPapp.py让Flask识别应用入口FLASK_DEBUG1开启调试模式代码修改后自动重载。--host127.0.0.1表示只在本机访问演示时如果有评委要求在手机上看效果改成--host0.0.0.0并保证同一局域网即可。操作命令激活虚拟环境venv\Scripts\activate安装依赖pip install -r requirements.txt初始化数据库flask init-db启动开发服务器flask run --port 5000启动测试pytest -v5.3 从注册到任务状态变化的一次完整演示路径答辩演示时不要从列表页开始评委想看的是行为闭环。建议按以下顺序操作先访问http://127.0.0.1:5000/auth/register注册一个新账号注册成功后会被重定向到登录页登录后添加三条任务其中一条内容故意不填验证前端后端都给出了错误提示然后勾选第一条任务标记为完成刷新页面确认状态保持最后点删除按钮清理任务。操作的同时打开浏览器开发者工具的Network面板让评委看到每次提交都是POST请求并返回302这个细节能证明你理解了“表单提交后重定向”的HTTP语义。最后一招是演示完测试用例在浏览器操作完成后切回终端执行pytest -v让评委看到一轮绿色通过。测试代码和数据库是现成的演示成本几乎为零却能把项目从“能跑”提升到“可验证”的层面。如果现场时间不够至少挑test_basics.py里的登录重定向用例跑一遍配合上一章的login_required装饰器讲解足够覆盖大部分提问。本文还有配套的精品资源点击获取