Python Flask高校学生就业信息系统开发指南:从框架选型到部署
大概在每年的毕业季前后我总能收到一堆类似的私信老师/学长/博主我想做一个高校学生就业信息系统用flask还是djangoPycharm怎么配置数据库到底怎么设计说实话这类题目确实是每年计算机专业毕业设计里出现频率最高的题材之一而且很多同学都会在flask和django之间反复横跳最后代码写了一半推倒重来。这篇博文我就围绕“Python基于flask框架高校学生就业信息系统”来聊一整个完整方案从flask与django的框架选型逻辑讲起到就业信息系统的核心模块拆解、数据库表设计、关键功能编码实现再到Pycharm开发环境配置和真机部署时容易踩的坑。标题里既然同时出现了flask和django我也会把两者在类似项目里的实际差异讲清楚帮你彻底想明白你到底该选谁。无论你是准备做毕业设计、课程设计还是单纯想练手搞一个SSM之外的技术栈项目这篇文章都能给出一套可以直接“抄作业”的落地路线。但先说清楚这篇文章不是让你复制粘贴交差的“代做”思路而是让你在理解原理的基础上把项目真正跑起来答辩的时候敢说每个函数是干嘛的。下面进入正题。1. 项目整体设计与框架选型为什么flask和django看似竞争却各有各的定位1.1 高校学生就业信息系统到底是一个什么样的系统先把题目拆开看。“高校学生就业信息系统”本质上是一个面向高校就业办、企业和学生三类用户的信息管理平台。它的典型业务逻辑是就业办管理员发布招聘会通知、审核企业资质和岗位信息企业注册后可以发布职位、接收学生简历学生在系统里维护个人简历、浏览岗位、投递简历、查看录用通知。如果再往完整一点做还会包括就业协议管理、就业数据统计报表、辅导员审核等模块。很多人觉得做一个管理系统就是“增删改查”这句话说对了一半。增删改查确实是系统的地基但不同角色的数据流转、权限控制、状态流转才是这类信息系统的真正难点。举个例子学生投递一份简历后企业的HR在后台看到的不能只是一条静态记录还需要能查看学生简历详情、标记面试状态待筛选、已邀约、已通过、已拒绝与此同时学生端也要同步看到这个状态。这种围绕一个“业务对象”在不同角色之间流转的机制正是信息管理系统区别于普通CRUD页面的核心所在。1.2 flask与django的选型逻辑为什么标题里同时出现了两个框架标题里同时出现了flask和django这很符合初学者纠结的实际情况。不少同学的选题模板是从学长那儿拿的原本写的是flask但搜索引擎又疯狂推荐django于是满头问号。我直接给结论如果你的项目以“管理系统”为主界面不需要太花哨后端逻辑需要快速输出答辩时讲得清楚那flask是更轻量、更直接的选择。flask本身很精简路由、请求处理、模板渲染都是内置的核心能力数据库操作交给SQLAlchemy用户认证用Flask-Login表单用Flask-WTF需要什么装什么整个项目的代码结构你都能完全掌控。django则是一个“全家桶”框架自带Admin后台、ORM、认证系统、表单处理、模板引擎等。它适合大型项目、快速搭建后台管理界面很爽但是对初学者来说django的目录结构、settings配置、app划分、中间件机制等概念一开始会比较绕。你做一个就业信息系统如果ahrefdjango的手段反而会被框架的学习曲线占用大量时间。我自己给学生的建议是如果你是打算把这个项目作为毕设且你已经能用Python写基本逻辑优先flask如果你未来想从事Python Web开发、想深入了解DRFDjango REST Framework继而做前后端分离项目那就直接django起步。但无论选哪个核心的设计思路是一样的你要把“用户-角色-业务数据”这几个维度理清楚。这个项目选flask因为它在保证功能完整的前提下代码量更少调试更直观。1.3 Pycharm在整个项目里的角色不只是编辑器而是开发环境的基础设施很多初学者把Pycharm当成一个普通的“写代码的软件”这是对它的误解。在Python Web开发里Pycharm承担了项目虚拟环境管理、解释器配置、调试器、数据库面板、Git集成等多个角色的组合。尤其是虚拟环境配置这一项如果没做对后面很容易出现“我明明pip install了flask为什么运行说ModuleNotFoundError”这种经典问题。在本项目里我建议的Pycharm配置方式是新建项目时选择Virtualenv虚拟环境Python解释器选择你已经安装好的Python 3.8至3.11之间的版本不建议直接上最新版部分第三方库兼容性可能滞后然后在这个虚拟环境内部安装flask、flask-sqlalchemy、flask-wtf、flask-login等依赖。Pycharm会自动识别当前项目所用的虚拟环境你后面在Terminal面板里执行的pip install命令也会自动装进这个环境避免系统全局Python环境被搞乱。2. 核心模块拆解与数据库设计把所有功能落到表结构上2.1 功能模块划分从用户故事推导系统边界在动手写代码之前我习惯先把系统的“用户故事”写出来。所谓用户故事就是站在每个角色的角度去描述“我想要做什么”。这个就业信息系统我整理出来用户故事大概是这样学生用户注册登录、完善个人信息、维护教育经历/实习经历/技能证书、浏览岗位列表、按关键词搜索岗位、投递简历、查看投递状态、查看系统通知。企业用户注册登录最好由管理员审核通过后才可登录、发布招聘岗位、编辑岗位、查看收到的简历列表、标记简历筛选状态、发出面试邀约。管理员用户管理学生账号、管理企业账号、审核企业注册、审核岗位发布、发布招聘会通知、查看统计报表各类专业就业人数、就业率等。把用户故事列出来之后系统的模块边界就清楚了。我们可以把整个系统划分为用户认证模块含角色权限控制、学生信息管理模块、企业信息与岗位管理模块、简历投递与筛选模块、通知公告模块、后台统计模块。这六个模块基本覆盖了题目的核心需求。2.2 数据库表设计六个核心数据表打通业务链路数据库设计是整个项目里最值得花时间琢磨的部分。很多人图快直接建一张user表把所有字段塞进去后面改到怀疑人生。我建议按照业务对象拆分表并理清它们之间的外键关系。下面是本项目比较合理的核心表结构学生表studentid主键user_id关联用户表外键学号、姓名、性别、出生日期、专业、年级、联系方式、邮箱个人简介、期望职位、期望薪资、简历附件路径企业表companyid主键user_id关联用户表外键企业名称、统一社会信用代码、企业性质国企/私企/外企、行业类别、规模、联系人、联系电话、企业邮箱、企业简介、是否审核通过岗位表jobid主键company_id关联企业表外键岗位名称、岗位类别、招聘人数、薪资范围、学历要求、工作地点、岗位描述、发布日期、是否有效简历表resumeid主键student_id关联学生表外键教育经历、实习经历、项目经历、技能标签、自我评价投递记录表applicationid主键student_id关联学生表外键job_id关联岗位表外键投递时间、状态待筛选、已邀约、已拒绝、已录用企业备注通知公告表noticeid、标题、内容、发布时间、发布人你可能会问已经有了学生表为什么还要单独建一个用户表这是初学者最容易忽略的设计细节。因为系统存在“学生、企业、管理员”三种角色如果每张业务表都自带一个账号密码字段会导致账号逻辑分散登录认证时到处查询。更合理的做法是单独设一个用户表user用role字段标识角色类型student/company/admin业务表通过外键跟user关联。这样一个接口就能完成登录和角色判断后续做权限控制也省事。2.3 为什么建议用Flask-SQLAlchemy而不是直接裸写SQL做这个项目数据库操作推荐用ORM对象关系映射方式。ORM的作用可以用一个类比的例子解释你不需要自己写“SELECT * FROM student WHERE id1”这样的SQL语句而是直接写“Student.query.get(1)”框架负责把Python代码翻译成SQL语句。对于毕设和课程设计用了ORM后代码可读性好答辩时也更容易解释。在flask生态里Flask-SQLAlchemy是最成熟、用得最多的ORM库它对多表关联查询、分页、数据迁移等都有很友好的支持。而且你定义的Python模型类class Student跟数据库表之间是一一对应的字段名、类型都写在代码里维护表结构的时候不用在SQL文件和代码间来回切换。这个项目的ORM模型代码大致长这样以学生表为例from flask_sqlalchemy import SQLAlchemy from datetime import datetime db SQLAlchemy() class User(db.Model): __tablename__ user id db.Column(db.Integer, primary_keyTrue) username db.Column(db.String(64), uniqueTrue, nullableFalse) password_hash db.Column(db.String(128), nullableFalse) role db.Column(db.String(20), nullableFalse) # student / company / admin create_time db.Column(db.DateTime, defaultdatetime.now) class Student(db.Model): __tablename__ student id db.Column(db.Integer, primary_keyTrue) user_id db.Column(db.Integer, db.ForeignKey(user.id), nullableFalse) name db.Column(db.String(32), nullableFalse) student_no db.Column(db.String(20), uniqueTrue, nullableFalse) major db.Column(db.String(64)) grade db.Column(db.String(20)) phone db.Column(db.String(20)) email db.Column(db.String(64)) intro db.Column(db.Text) user db.relationship(User, backrefdb.backref(student, uselistFalse))这里用到了db.relationship建立表之间的关系操作时可以直接通过student.user.username访问账号名很方便。用uselistFalse是因为一个用户只对应一个学生档案反过来就不适用。3. 实操过程与核心环节实现让就业信息系统真正跑起来3.1 环境搭建Pycharm里创建flask项目并配置虚拟环境我用Pycharm建项目时推荐这样一步步来打开Pycharm选择New Project左侧选Flask。如果你用的是社区版没有Flask模板选Pure Python也行后面手动安装flask即可本质没有区别。项目路径建议全英文命名比如“GraduateEmploymentSystem”别用中文路径否则后续有些扩展库加载容易出乱子。项目创建后在Pycharm底部找到Terminal面板依次执行下面的命令pip install flask flask-sqlalchemy flask-wtf flask-login这几行命令会安装flask核心、ORM扩展、表单扩展和登录扩展。装完后可以快速验证一下flask是否可用新建一个app.py写入最简单的启动代码from flask import Flask app Flask(__name__) app.route(/) def index(): return Hello, Flask if __name__ __main__: app.run(debugTrue)然后右键运行如果浏览器访问http://127.0.0.1:5000/能看到HelloFlask说明整个链路已经通了。这一步虽然简单但它是后面所有开发工作的基础一定要确保成功。接下来需要配置数据库连接。这个项目的数据量级别完全不需要上MySQL以外的重型数据库直接在本地用MySQL或SQLite都可以。从毕设答辩的角度讲用MySQL显得更正式从部署和调试方便程度讲SQLite零配置更省事。我建议开发阶段先用SQLite快速跑通业务最后部署时再切换成MySQL。在config文件里可以这样写import os class Config: SECRET_KEY your-secret-key SQLALCHEMY_DATABASE_URI sqlite:/// os.path.join( os.path.abspath(os.path.dirname(__file__)), employment.db ) SQLALCHEMY_TRACK_MODIFICATIONS False如果后续要切MySQL只需要把SQLALCHEMY_DATABASE_URI改成SQLALCHEMY_DATABASE_URI mysqlpymysql://root:passwordlocalhost/employment_db?charsetutf8mb4注意这里需要提前装好pymysql。切换之后中文乱码问题一般通过charsetutf8mb4就能解决。3.2 注册登录与角色权限控制一个系统最容易被拷问的部分就业信息系统的登录逻辑跟普通单用户系统不一样它必须实现“一个登录入口多种角色跳转”。我采用的做法是用户登录成功后把用户ID和角色存进session然后写一个装饰器用来保护需要登录才能访问的页面。用户模型里的密码不能明文存储。很多人写毕设时直接把用户密码明文存在数据库里这在演示时没问题但答辩老师一问“密码安全怎么考虑”就露怯了。这里建议用werkzeug.security提供的generate_password_hash和check_password_hash来做密码哈希与校验from werkzeug.security import generate_password_hash, check_password_hash # 注册时 user User(usernameusername, password_hashgenerate_password_hash(password), rolerole) # 登录校验时 if user and check_password_hash(user.password_hash, password): session[user_id] user.id session[role] user.role注册表单可以用Flask-WTF来定义它最大的好处是内置CSRF防护和表单校验。比如学生注册时需要的字段就可以定义成from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SelectField from wtforms.validators import DataRequired, Length, Email class StudentRegisterForm(FlaskForm): username StringField(用户名, validators[DataRequired(), Length(3, 20)]) password PasswordField(密码, validators[DataRequired(), Length(6, 32)]) name StringField(姓名, validators[DataRequired()]) student_no StringField(学号, validators[DataRequired(), Length(8, 12)]) major StringField(专业, validators[DataRequired()])表单校验通过后再往数据库插入新用户和学生档案两条记录并且用事务保证数据一致性。这地方有个常见坑如果先插user拿到user.id再插student中间任何一步报错可能导致user存在但student不存在。这时候需要用到db.session.begin_nested()或者最简单的做法——先把user加进session但暂不commit然后通过db.session.flush()获取user.id再创建student最后统一commitdb.session.add(user) db.session.flush() # 获取 user.id 且不提交事务 student Student(user_iduser.id, ...) db.session.add(student) db.session.commit()3.3 岗位发布与列表页分页、搜索、条件筛选的组合拳岗位模块是就业信息系统的核心业务它涉及企业端发布、学生端查看与搜索、管理员审核三个入口。其中最有代表性的是岗位列表页。这里我建议实现三个能力关键词搜索比如输入“Python”、条件筛选按工作地点/学历要求/薪资范围、分页展示。flask里做分页非常简单SQLAlchemy的paginate方法可以直接返回一个Pagination对象from flask import request app.route(/jobs) def job_list(): page request.args.get(page, 1, typeint) keyword request.args.get(keyword, , typestr) query Job.query.filter(Job.is_active True) if keyword: query query.filter(Job.title.contains(keyword)) pagination query.paginate(pagepage, per_page10, error_outFalse) jobs pagination.items return render_template(job_list.html, jobsjobs, paginationpagination, keywordkeyword)对应的模板分页组件一般长这样div classpagination {% if pagination.has_prev %} a href{{ url_for(job_list, pagepagination.prev_num, keywordkeyword) }}上一页/a {% endif %} span第 {{ pagination.page }} / {{ pagination.pages }} 页/span {% if pagination.has_next %} a href{{ url_for(job_list, pagepagination.next_num, keywordkeyword) }}下一页/a {% endif %} /div为什么用request.args.get(page, 1, typeint)来接收页码而不是直接取字符串因为如果用户手动在URL输入?pageabc这个写法会静默地把page当成默认值1处理不会直接抛500错误。这种健壮性处理在答辩演示时也算一个小亮点。3.4 简历投递与状态流转如何避免重复投递和数据混乱学生投递简历是最容易出逻辑漏洞的环节。第一次做这类系统的人通常只想到“点击投递后插入一条记录”但完全没有考虑同一个学生对这个岗位重复点投递怎么办。不加约束的话数据库里会堆积大量重复的投递记录企业端看到一个学生简历出现三四遍观感很差。解决这个问题有两条路一是在投递前查询判断二是给表加唯一约束。我更推荐双保险class Application(db.Model): __tablename__ application id db.Column(db.Integer, primary_keyTrue) student_id db.Column(db.Integer, db.ForeignKey(student.id), nullableFalse) job_id db.Column(db.Integer, db.ForeignKey(job.id), nullableFalse) status db.Column(db.String(20), defaultpending) apply_time db.Column(db.DateTime, defaultdatetime.now) is_active db.Column(db.Boolean, defaultTrue) __table_args__ ( db.UniqueConstraint(student_id, job_id, nameuniq_student_job), )当数据库层面已经有唯一约束后即使两个请求同时打进来也只有一个能成功插入另一个会触发IntegrityError。在视图层再提前查一次是为了能给出更友好的用户提示而不是让用户看到一条数据库报错页面。视图层判断可以这样写app.route(/job/int:job_id/apply, methods[POST]) login_required def apply_job(job_id): student Student.query.filter_by(user_idsession[user_id]).first() existing Application.query.filter_by(student_idstudent.id, job_idjob_id).first() if existing: flash(你已经投递过这份岗位请勿重复投递, warning) return redirect(url_for(job_detail, job_idjob_id)) # 在这里创建投递记录 app_record Application(student_idstudent.id, job_idjob_id, statuspending) db.session.add(app_record) db.session.commit() flash(投递成功请等待企业反馈, success) return redirect(url_for(my_applications))投递之后的状态流转我建议用一组状态常量管理而不是到处写死字符串。可以在application模型文件里定义class ApplicationStatus: PENDING pending INTERVIEW interview REJECTED rejected ACCEPTED accepted这样后续写判断时用ApplicationStatus.ACCEPTED避免因为“待筛选/邀约/拒绝”等中文写法不统一导致状态匹配不上。3.5 数据可视化与统计报表让项目在答辩时更出彩多数学生做就业信息系统只做到了“信息录入与展示”但高校就业办最关心的其实是就业数据统计分析。哪怕你的项目不要求开发报表模块我也强烈建议至少做两个简单的统计图表比如“各专业就业人数柱状图”和“企业性质分布饼图”。实现方式不需要很复杂可以用ECharts前端通过接口从后端拿JSON数据然后渲染图表。后端给统计接口返回的数据格式大致是app.route(/api/stats/major) def stats_major(): results db.session.query( Student.major, func.count(Application.id) ).join(Application, Student.id Application.student_id) \ .filter(Application.status accepted) \ .group_by(Student.major).all() data [{name: major, value: count} for major, count in results] return jsonify(data)这里核心用到了ORM里的聚合查询func.count执行COUNT统计group_by做分组。如果不用ORM对应的SQL是SELECT student.major, COUNT(application.id) FROM student JOIN application ON student.id application.student_id WHERE application.status accepted GROUP BY student.major;两条路都能得到结果但用ORM的写法不需要在Python代码里拼SQL字符串也不容易出SQL注入问题。前端页面用ECharts渲染时只需要通过fetch(/api/stats/major)拿到数据然后chart.setOption把它填进柱状图即可。这个模块虽然代码量不大但视觉效果非常加分答辩时老师一看就觉得系统“有数据分析能力”。4. 常见问题与排查技巧实录Pycharm/Flask/Django高频坑点对照4.1 虚拟环境相关pip没装错但就是import不到模块这是Pycharm里flask开发最经典的坑在Terminal里显示pip install flask成功但一运行代码却提示ModuleNotFoundError: No module named flask。绝大多数情况下是因为Pycharm左下角解释器选择的是系统的全局Python环境而pip却装进了项目的虚拟环境或者反过来。排查方法很简单在Pycharm右下角状态栏查看当前项目使用的解释器路径。如果路径显示的是C:\Python38\python.exe这类全局路径说明没有使用虚拟环境。解决办法是打开“Settings - Project - Python Interpreter”选择已有虚拟环境的解释器或者新建一个虚拟环境并安装依赖。一旦解释器选对了Terminal里执行pip list就能看到flask已经存在。判断解释器是否匹配的经验是在Pycharm的Terminal里执行python -c import flask; print(flask.__version__)能正常输出版本号就说明环境没问题如果报错就不要继续在那折腾代码了先解决环境再说。4.2 Flask-SQLAlchemy模型改动后数据库没变化初学者用flask-sqlalchemy时经常遇到一个问题改了模型类的字段启动程序后数据库表结构没有同步更新。比如给User表加了一个avatar字段重启项目发现数据库还是旧表直接查询新增字段就报错。这是因为Flask-SQLAlchemy默认情况下不会自动迁移表结构。处理方式有两种第一种适合开发前期直接删除原来的数据库文件或用db.drop_all()再db.create_all()重新建表数据量小的时候最省事。第二种适合已经积累了正式数据的中后期安装flask-migrate做完整的迁移管理。对于毕设项目我建议直接做好规划前期设计表结构尽量一次到位避免反复重建。这里也提醒一下db.create_all()只会创建不存在的表不会修改已存在的表。所以当你改了模型字段后最稳妥的重建方式是先执行db.drop_all()再执行db.create_all()。但是drop_all会清空所有数据操作前一定要确认里面没有不可丢失的记录。4.3 flask与django的CSRF防护思路差异CSRF跨站请求伪造是Web表单最常见的攻击方式之一。它的原理很简单攻击者诱导你在已登录的浏览器里访问一个恶意网站这个网站向你的目标系统发送一个伪造的POST请求由于你在目标系统的cookie仍然有效服务器会认为这个请求是你本人发起的。在flask里如果用了Flask-WTF每个表单创建时都要传一个form.hidden_tag()里面会渲染一个包含CSRF token的隐藏字段。这个token由服务器生成并存入session提交时服务器会校验表单里的token和session里的token是否一致。如果忘记在模板里写入form.hidden_tag()会出现“CSRF token missing”的报错。这是flask新手最常遇到的坑之一。django的做法也类似它默认全局开启CSRF中间件模板里的表单需要加{% csrf_token %}。select框架不同但思路完全相同。如果你在项目里使用fetch发送AJAX请求CSRF token还需要放到请求头里flask中可以通过获取表单字段值后加到headersdjango则约定俗成地叫X-CSRFToken。这部分不管做毕设还是以后工作都很有用建议格外留意。4.4 Pycharm运行flask项目时的端口占用与debug模式问题在Pycharm里运行flask项目如果之前有一次程序没有正常退出再次运行时可能提示端口被占用OSError: [Errno 98] Address already in use。这个问题的解决办法很简单找到占用端口的进程并结束它。在Windows下可以用命令netstat -ano | findstr 5000 taskkill /PID 对应的PID /F在macOS或Linux下用lsof -i :5000 kill -9 对应的PID另外flask的app.run(debugTrue)在开发时一定要打开。debug模式有两个作用一是代码改动后自动加载不用手动重启二是页面报错时会显示详细的错误堆栈方便定位问题。但正式部署时千万不要开着debug模式因为它会暴露本地文件路径和源码信息还会提供一个交互式调试终端等于把服务器大门敞开给别人进安全隐患极大。4.5 Pycharm配置数据库面板和前端模板时的常见卡点Pycharm的Database面板对于调试数据库内容非常方便它能可视化地查看表数据、执行SQL语句、甚至直接看到ORM查询对应的SQL。但很多第一次用的人不会配置。在Pycharm右侧打开Database面板点击加号选择Data Source下的MySQL然后填写主机、端口、用户名、密码测试连接成功后就能在IDE里直接查看和编辑数据表了。如果提示缺少驱动按照提示下载驱动即可。这个面板跟Navicat这类专业数据库工具比胜在不用切换窗口排查数据问题效率很高。前端模板渲染时还有一个经典误区flask使用Jinja2模板引擎模板里写变量用双花括号{{ variable }}写逻辑用{% if %}注释用{# #}。如果你直接按HTML注释写!-- --内容会出现在最终渲染后的页面里虽然不影响功能但显得不专业。另外Jinja2模板中{{ url_for(view_function_name) }}是动态生成URL的标准方式不要在模板里硬编码路径否则你改了路由规则后所有链接都得跟着改。4.6 性能优化与代码组织的进阶建议虽然毕设项目数据量不大但如果想要让项目显得“上档次”代码组织方式一定要提前设计好。千万不要把所有路由都堆在app.py里那样几百行写下来越往后越痛苦。推荐将项目按模块拆分apps/ 目录下分模块比如Apps/Auth/Auth.py、Apps/Student/Student.py、Apps/Company/Company.py、Apps/Admin/Admin.py。Models/ 目录放所有数据库模型User.py、Student.py、Company.py、Job.py、Application.py、Notice.py 一个模型一个文件。Template/ 按角色分目录student/、company/、admin/ 分开放模板页面多了之后才知道这种方式有多香。Static/ 放CSS、JS、图片也按角色或功能分子目录。模块化拆分之后app.py只需要负责创建应用实例、注册蓝图Blueprint、初始化数据库扩展。蓝图是flask里组织路由最核心的工具比如把学生相关的所有路由封装在一个蓝图中然后注册到主应用上。蓝图带来的直接好处是不同角色的代码物理隔离查找问题范围小多人协作时冲突少。5. 从开发到部署上线的完整经验开发完成后很多人觉得项目能本地运行就算完事了但答辩时老师很可能追问“你的系统能在服务器上跑起来吗”。这里我建议至少做到可以被局域网访问或者干脆部署到一台能外网访问的服务器上。框架层面flask和django在部署上的套路是相似的生产环境不要用flask自带的开发服务器而是用gunicorn或uWSGI作为WSGI服务器前面再挂一个Nginx做反向代理和静态文件处理。原因很简单flask开发服务器的性能和安全强度都不足以应对真实流量。部署时需要注意的是数据库迁移。如果你开发时用的是SQLite部署时想切成MySQL需要提前把数据表结构同步过去。对于这种体量的系统最省事的方式是部署环境安装MySQL后把SQLALCHEMY_DATABASE_URI改成MySQL连接串然后启动一个一次性脚本调用db.create_all()自动建表。接着再手动导入必要的初始数据比如管理员账号、常用专业目录等。如果你选择宝塔面板这类运维工具来部署django项目很多人觉得省事但说实话我不建议一个毕设项目为了部署去研究面板的反向代理、Python项目管理器等一系列概念。直接把flask项目打进Docker镜像反而是更轻、更可控的方案只是学习曲线稍微陡一点。我个人的经验是如果你时间充裕就研究一下supervisorgunicornNginx这套经典组合懂了之后你以后做Python Web项目的部署都心里有底如果临近答辩只有一两天那先把项目在Pycharm里跑得毫无问题、功能完整演示一遍就已经比一大半人强了。根据我这些年陪跑毕业设计项目下来的体会这类信息管理系统做得好不好关键在于两点一是设计方案时有没有真正理解业务流程二是代码组织是否整洁、逻辑是否严谨。框架选flask还是django真的没那么重要重要的是你把系统当成一个真实可用的产品去设计而不是当成课堂作业完成任务。只要数据库设计合理、核心流程闭环、代码结构清晰你就可以昂着头走进答辩教室。