ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python+Vue校园招聘系统:全栈开发实战与前后端分离解析

Python+Vue校园招聘系统:全栈开发实战与前后端分离解析 1. 项目概述与核心需求解析1.1 这是一个什么样的项目python基于vue的校园招聘系统光看这个名字很多初学者会觉得它就是一个普通的管理系统随便搭个框架写几个页面就完事了。但实际做下来你会发现它几乎涵盖了Web全栈开发的大部分核心知识点用户认证、角色权限、数据建模、前后端分离、接口联调、文件上传、搜索排序、部署上线。如果你正在纠结毕设选题或者想找个练手项目巩固全栈能力这个项目是非常经典的切入点。这个系统面向的是高校场景核心用户是学生和企业两头。学生需要注册登录、维护简历、浏览职位、投递简历、查看面试通知企业需要注册公司账号、发布职位、查看收到的简历、发起面试邀约。除了这两端通常还需要一个管理员后台负责审核企业和职位信息、处理举报、做基础数据统计。三个角色、两套前端界面加上后端接口和数据库设计工程量对于一个人来说刚好适中。1.2 技术选型背后的考虑标题里同时出现了Django和Flask这是很多人的疑惑点到底该用哪个我说下实际开发中的体会。Django的优势在于全家桶。自带的ORM、Admin后台、认证系统、表单处理、中间件机制几乎覆盖了Web开发的常见需求。写校园招聘系统这种带用户体系、数据关系相对复杂的业务Django的模型管理能帮你省掉大量重复代码。尤其是它的Admin后台可以用来快速管理数据在开发阶段调试非常舒服。Flask的优势在于灵活。它只提供最基础的请求路由和模板渲染其他一切都靠第三方扩展组合。好处是你对项目的掌控粒度更细适合想了解接口层面工作原理的人坏处是所有东西都要自己拼比如数据库迁移要装Alembic认证要自己写装饰器或集成Flask-Login项目结构也需要自己设计。我的建议是如果你希望快速做出一个完整可演示的项目优先选Django如果你希望代码结构更轻、更愿意自己编排逻辑或者之前已经熟悉Flask选Flask也不差。下面正文统一以Django为主路线来讲在关键的差异点会补一句Flask的做法方便两边对照。1.3 环境与工具为什么格外强调PyCharm热词里反复出现pycharm安装教程、pycharm激活、pycharm中文插件说明很多新手卡在了环境这一步。实际上PyCharm对于这类项目的重要性被低估了它不只是个编辑器更是一个集成的开发工作台。用PyCharm打开Django项目后它可以识别manage.py直接提供Run/Debug配置一键启动开发服务器。它内置的Database工具面板可以查看MySQL或SQLite的表结构、执行SQL查询调试接口的时候不用来回切Navicat。前端部分PyCharm专业版支持Vue单文件组件的高亮、模板里的变量跳转、终端集成开一个IDE就能同时处理前后端两端代码。社区版虽然不支持Vue语法高亮但装个Vue插件也能凑合用不影响功能开发。2. 整体设计与技术方案选型2.1 为什么选前后端分离架构说到校园招聘系统的架构常见的做法有两种一是用Django的模板系统直接渲染页面服务端把HTML生成好发给浏览器二是前后端分离后端只提供JSON接口前端用Vue框架渲染页面。两种方案在毕设和实际项目中都很常见但我个人建议选择前后端分离。原因有三点第一需求变化时维护成本低。校园招聘系统涉及学生端、企业端、管理端界面逻辑各不相同。分离之后后端不需要关心页面怎么展示只负责把数据接口给好前端只管调用接口、渲染组件。改页面样式不会动后端代码改接口逻辑也不会影响页面结构。第二就业方向对口。现在企业里做Java、Python、Go的基本上都是写后端接口前端岗位全是Vue、React。用前后端分离完成这个项目等于提前演练了一遍真实的工作模式。第三Vue生态对这类管理型系统支撑非常成熟。Element UI、Ant Design Vue这类组件库提供了现成的表格、表单、弹窗、分页组件招聘系统的界面很多就是表单加列表的组合用组件库能省很多CSS的功夫。2.2 后端框架的模块拆解Django开发这类系统的常规姿势是拆App。不要把所有的模型和视图写在一个文件里而是按业务边界拆成多个子应用。校园招聘系统我习惯拆成这样account学生和企业的注册、登录、Token认证、个人资料管理。因为系统里有两类普通的业务用户用户名密码认证加用户类型字段来区分非常直接。company企业管理相关包括企业信息维护、企业资质资料上传。job职位模块包含职位的增删改查、上下架、筛选搜索、职位分类。resume学生简历模块包括简历的编辑维护、附件简历上传。application投递记录模块学生投递职位后生成一条投递记录企业可以查看并按状态筛选。interview面试通知企业发起面试邀请学生确认或者拒绝。admin管理员端接口负责企业审核、职位审核、数据统计。每个App只负责自己的事情模型之间通过外键关联。比如投递记录属于一个学生关联一个职位职位属于一个企业。这种结构逻辑清晰后面定位Bug的时候凭问题的表象就能快速定位到对应的App。2.3 数据库设计需要注意的关系招聘系统的核心关系并不复杂但有几个关系需要提前想清楚否则做一半就会返工。用户表是基础。学生和企业都存入同一个用户表用一个user_type字段区分比分成学生表和企业表要容易处理。Django自带的User模型可以直接扩展通过OneToOneField关联一个Profile表存角色信息。职位表关联企业用户外键指向User表加一个on_deletemodels.CASCADE企业用户被删除时关联职位一并删除。职位还要考虑上下架状态、审核状态这直接关系到列表页展示什么数据。简历表和学生用户一对一。简历内容除了基本资料可能还包括自我评价、教育经历、项目经历。我建议不要把经历类数据直接塞进简历表的字段里而是拆成Education和Project两张子表通过外键关联简历主表。这样学生在编辑简历时可以动态添加多条经历前端的渲染也简单遍历子表数据即可。投递记录表是核心的业务表字段设计上要把状态机想好。学生投递之后状态从已投递开始企业可以更新为被查看,通过初筛,面试邀请,已录用等。状态字段用IntegerField存数字常量比存字符串更省空间也能避免枚举值拼写错误。为了查重还需要在投递记录上加一个UniqueConstraint约束同一个学生不能重复投递同一个职位。3. 环境准备与项目脚手架搭建3.1 Python与PyCharm环境配置要点开始之前先把基础环境准备好。Python版本建议3.10或3.11这两个版本对Django和Vue相关工具链的兼容性都很稳定。不建议上来就装3.13某些编译型依赖可能还没有对应的预编译包。PyCharm方面如果你手头有专业版最好没有的话社区版也完全够用。国内环境下安装PyCharm时容易出现的一个问题是新建项目时选择了New environment using Virtualenv但解释器路径选到了系统Python而不是虚拟环境。解决方法是项目创建后在Settings - Project - Python Interpreter里手动把解释器切换到项目目录下的venv文件夹。安装依赖时千万不要直接在终端乱pip install。先新建虚拟环境再通过requirements.txt进行管理。Django项目的核心依赖大致是django4.2,5.0 djangorestframework django-cors-headers djangorestframework-simplejwt mysqlclient # 如果用MySQL的话 Pillow # 处理图片上传这里要特别说明django-cors-headers这个库前后端分离项目必装。Django默认不允许其他域名的JavaScript请求后端接口不带这个库的话Vue页面调接口会一直报跨域错误。安装之后在settings.py的INSTALLED_APPS里注册corsheaders再在MIDDLEWARE里加上CorsMiddleware开发阶段可以直接设CORS_ALLOW_ALL_ORIGINS True省心。等项目部署上线前再收紧跨域策略。3.2 用命令初始化Django项目环境准备好之后用命令行初始化项目骨架。django-admin startproject recruitment cd recruitment python manage.py startapp account python manage.py startapp job python manage.py startapp resume python manage.py startapp application python manage.py startapp interview python manage.py startapp company注意一点startproject生成的外层目录名和内层项目名不要用一样的名称否则导入时容易混淆。上面这种结构外层是刚刚创建的recruitment文件夹内层还有个manage.py同级的recruitment配置包。平时启动项目都从外层目录执行python manage.py runserver。初始化完成后先编辑settings.py。把新创建的App全部注册进INSTALLED_APPS配置数据库为MySQL。如果SQLite用起来也行但招聘系统最后可能需要演示数据MySQL对并发和数据量都比较友好。数据库配置如下DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: recruitment, USER: root, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, } }别忘了先启动MySQL服务再执行下面的迁移命令python manage.py makemigrations python manage.py migrate python manage.py createsuperusermakemigrations这一步经常有人报错No changes detected原因通常是App还没注册进INSTALLED_APPS或者App目录下还没写models。检查一下这两个点基本就能解决。3.3 前端项目初始化Vue部分我用的是Vue 3 Vite Element Plus组合。Vue CLI虽然稳定但Vite启动速度快很多开发体验好。创建Vue项目的命令npm create vuelatest frontend cd frontend npm install npm install axios element-plus vue-router pinia目录结构上src下按views、components、router、api、stores组织。views里按角色区分比如student/、company/、admin/三个文件夹各自放对应角色的页面。api文件夹下按业务模块拆文件job.js、resume.js、application.js每个文件里统一封装axios请求。为了保证前后端开发时的接口联调顺畅在vite.config.js里配置代理export default { server: { port: 5173, proxy: { /api: { target: http://127.0.0.1:8000, changeOrigin: true } } } }这样前端可以直接请求/api/xxxVite开发服务器会代理到Django后端就避开了开发阶段最烦人的CORS问题。4. 核心功能模块设计与代码实现4.1 用户注册、登录与JWT认证系统里两类注册用户学生和企业信息字段差异不小。Django自带的User模型可以覆盖账号密码、邮箱等基础信息但企业还需要公司名称、统一社会信用代码、营业执照等。我采用的方式是User模型加一个OneToOneField的Profile扩展。先设计Profile模型# account/models.py from django.contrib.auth.models import User from django.db import models class Profile(models.Model): USER_TYPE_CHOICES [ (student, 学生), (company, 企业), (admin, 管理员), ] user models.OneToOneField(User, on_deletemodels.CASCADE, related_nameprofile) user_type models.CharField(max_length20, choicesUSER_TYPE_CHOICES, defaultstudent) phone models.CharField(max_length20, blankTrue) company_name models.CharField(max_length100, blankTrue) credit_code models.CharField(max_length30, blankTrue) avatar models.ImageField(upload_toavatar/, blankTrue) def __str__(self): return f{self.user.username} - {self.get_user_type_display()}注册接口的核心逻辑就是先调用Django内置的authenticate确认用户名密码没问题再把关联的Profile建起来。这一步很多新手容易出错的地方是创建User之后忘了创建Profile或者创建Profile时没有同步user_id导致后面查询用户类型时全是None。所以创建完User之后一定要同步把Profile一起创建了这个顺序不能反。登录认证我用的是SimpleJWT。安装djangorestframework-simplejwt之后在settings.py里配置REST_FRAMEWORK的DEFAULT_AUTHENTICATION_CLASSES为JWTAuthentication。登录成功后返回的access token前端会存到localStorage里每次请求带上Bearer头。对于像投递简历这种敏感操作后端用IsAuthenticated权限类来保护接口。SimpleJWT自带的路由可以直接用# recruitment/urls.py from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns [ path(api/token/, TokenObtainPairView.as_view(), nametoken_obtain_pair), path(api/token/refresh/, TokenRefreshView.as_view(), nametoken_refresh), ]4.2 职位发布与检索接口职位模块是系统里最核心的业务模块。数据模型字段要做好规划因为招聘系统里职位搜索条件是最多的关键词搜索、城市筛选、薪资范围、工作经验要求、学历要求。这些条件如果字段设计不全后面检索接口会非常别扭。职位模型示例# job/models.py from django.db import models from django.contrib.auth.models import User class Job(models.Model): STATUS_CHOICES [ (draft, 草稿), (open, 招聘中), (closed, 已关闭), (rejected, 审核未通过), ] company models.ForeignKey(User, on_deletemodels.CASCADE, related_namejobs) title models.CharField(max_length100) category models.CharField(max_length50) city models.CharField(max_length50) salary_min models.IntegerField() salary_max models.IntegerField() experience_required models.CharField(max_length20) education_required models.CharField(max_length20) description models.TextField() status models.CharField(max_length20, choicesSTATUS_CHOICES, defaultdraft) created_at models.DateTimeField(auto_now_addTrue) updated_at models.DateTimeField(auto_nowTrue)招聘职位的发布流程和企业审核状态相关。企业发布职位时默认状态为draft或pending管理员审核通过后状态变为open才能出现在学生端职位列表里。这一步状态机的设计很关键它保证学生只能看到经过管理员审核的职位避免垃圾职位刷屏。职位检索接口用Django REST Framework的viewsets来实现配合django-filter做参数过滤。在视图里重写get_queryset根据当前用户角色返回数据学生端只返回已审核且招聘中的职位企业端返回自己发布的全部职位管理员端能看所有职位。from rest_framework import viewsets, permissions from rest_framework.response import Response from django_filters.rest_framework import DjangoFilterBackend class JobViewSet(viewsets.ModelViewSet): queryset Job.objects.all() serializer_class JobSerializer permission_classes [permissions.IsAuthenticated] filter_backends [DjangoFilterBackend] filterset_fields [city, category, salary_min, experience_required, education_required] def get_queryset(self): user self.request.user if user.profile.user_type student: return Job.objects.filter(statusopen) return Job.objects.filter(companyuser)搜索关键词这块我用的是django-filter的CharFilter配合icontains模糊匹配职位标题和职位描述。实际项目中如果要做得更精细可以引入全文搜索框架但对于校园招聘这个量级icontains足够用了。4.3 简历管理与投递逻辑简历是所有学生用户的核心资产设计上采用主表加经历子表的方式。# resume/models.py class Resume(models.Model): student models.OneToOneField(User, on_deletemodels.CASCADE, related_nameresume) full_name models.CharField(max_length50) email models.EmailField() phone models.CharField(max_length20) education models.TextField(blankTrue) experience models.TextField(blankTrue) skills models.TextField(blankTrue) attachment models.FileField(upload_toresume_files/, blankTrue) updated_at models.DateTimeField(auto_nowTrue)简历创建后需要提供编辑、查看、上传附件三个接口。附件上传要注意处理上传大小和文件类型在视图里加一个限制超过5MB直接报异常文件后缀要过滤掉exe等危险类型。这块虽然不难但很多项目都是在这里被审查老师问到了。投递逻辑里的一个关键点是防重复投递。学生端重复点击投递按钮如果前端没做防抖会有连续多次POST请求打到后端。数据库层要先做约束# application/models.py class Application(models.Model): STATUS_CHOICES [ (submitted, 已投递), (viewed, 被查看), (interview, 面试中), (accepted, 已录用), (rejected, 不合适), ] student models.ForeignKey(User, on_deletemodels.CASCADE, related_nameapplications) job models.ForeignKey(Job, on_deletemodels.CASCADE, related_nameapplications) status models.CharField(max_length20, choicesSTATUS_CHOICES, defaultsubmitted) created_at models.DateTimeField(auto_now_addTrue) class Meta: constraints [ models.UniqueConstraint(fields[student, job], nameunique_application) ]有了数据库约束后接口层再做一次查询判断并返回友好提示你已投递过该职位。这样可以做到双重保险既避免重复数据又给用户清晰的反馈。企业端查看投递记录时分页是必须的。职位一旦热门投递数轻松过百一页全量返回会让前端渲染卡顿。小红书就不演示了直接在视图里加Django REST Framework自带的PageNumberPagination每页设置20条。前端配Element Plus的el-pagination组件看起来就很专业。4.4 面试通知与消息提醒企业看完简历觉得合适下一步是发起面试。面试通知表比较简单字段包括投递关联、面试时间、面试地点、面试说明再带一个确认状态。计算置信度可以加一个面试日历视图企业可以看到自己发布的职位下面所有待处理面试。学生关注的是有没有新的面试邀请在页面顶部做一个提醒按钮通过Unread计数显示醒目的小红点。后端提供一个未读数量接口# interview/views.py class UnreadInterviewCountView(APIView): def get(self, request): count Interview.objects.filter( application__studentrequest.user, is_confirmedFalse ).count() return Response({unread_count: count})当面试通知产生时除了在系统里有记录还可以在web前端做一个全局的el-message提醒。这些产品层面的细节会显著提升项目演示时的观感。5. 前后端联调与项目部署细节5.1 接口协议与联调规范前后端联调是这个项目里最容易混乱的阶段。我自己走过不少弯路最大的教训是接口返回格式必须统一。如果Django那边一会儿返回{code: 200, data: []}一会儿又直接返回数组前端axios的封装就没法做统一的错误处理和数据拦截。我的做法是封装一个统一的响应格式from rest_framework.response import Response def ok(dataNone, messagesuccess): return Response({code: 200, message: message, data: data}) def fail(code400, messageerror, dataNone): return Response({code: code, message: message, data: data})前端在axios的响应拦截器里统一判断code200就放行返回data非200就弹错误提示。这样联调阶段双方只需要核对字段名不需要处理各种接口风格差异。联调过程中需要经常用到的调试工具是Postman或Apifox。Apifox有一个好处是能自动根据Swagger或DRF的接口文档导入接口定义省去手写大量URL和参数的时间。把接口调试通过后再和前端对基本能减少一半的沟通成本。5.2 Vue页面与接口对接的实现细节以前端职位列表页为例展示整条联调链路。接口约定是GET /api/jobs/?page1keywordpythoncity上海。前端api/job.js里封装import axios from /utils/request export function getJobList(params) { return axios.get(/api/jobs/, { params }) } export function applyJob(jobId) { return axios.post(/api/applications/, { job: jobId }) }职位列表页用Element Plus的el-table展示数据。表格的loading状态一定要做否则接口慢的时候用户会误以为白屏是Bug。在data里维护一个loading变量请求发出去时置为truefinally里置为false。el-pagination的current-page和page-size也要和请求参数联动页码切换时重新请求接口而不是在前端做假分页。投递按钮的状态也需要根据投递记录动态变化。列表接口返回的数据里后端可以附带一个applied字段当前学生是否投递过。这样前端直接根据这个字段判断按钮是投递简历还是已投递禁掉按钮就不用每次点击都去查一遍投递记录。5.3 项目部署上线从开发机到服务器项目答辩或演示时如果只是本地跑一跑那部署这部分不用太深究。但如果你想把项目放到服务器上给导师或面试官远程访问需要把前后端都部署好。后端用Django的部署思路是Gunicorn管理进程Nginx分发请求静态文件交给Nginx处理。先在服务器上把代码pull下来创建虚拟环境安装依赖。然后配置环境变量把SECRET_KEY、数据库密码等敏感信息从settings.py中剥离出来。pip install gunicorn gunicorn recruitment.wsgi:application --bind 0.0.0.0:8000然后配置Nginx把/api开头的请求代理到本地的8000端口。前端的构建产物dist目录配成一个静态站点。server { listen 80; server_name your_domain; location /api/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { root /var/www/recruitment/frontend/dist; index index.html; try_files $uri $uri/ /index.html; } location /static/ { alias /var/www/recruitment/staticfiles/; } }部署阶段有几个常见的坑我后面在问题排查部分会展开讲。这里先提醒一句Django的DEBUG一定要设为False否则一旦报错浏览器会把完整的堆栈信息展示出来不但不安全还会暴露项目结构。5.4 Flask方案的关键差异说明前面整体用了Django路线但标题里既然提到了Flask也有相当一部分人会选它。这里把Flask版本的关键差异点做个对照。功能点Django做法Flask做法数据库模型models.py定义类Flask-SQLAlchemy数据迁移migrate内置Alembic认证权限jwt restful权限Flask-JWT-Extended 自定义装饰器后台管理Admin自带Flask-Admin表单校验自带Form/SerializerMarshmallow或手动校验项目结构按App切分按蓝图Blueprint切分Flask本身没有Django那么多默认约定你写的每个文件都是自己搭建出来的。好处是理解更深坏处是坑也更多。比如创建数据库表的时候必须先db.create_all()否则SQLAlchemy不会自动建表Blueprint要挨个注册到app上少一步就会出现404错误。如果你的基础比较薄弱建议还是用Django能省掉很多跟业务无关的配置精力。6. 常见问题与排查技巧实录6.1 跨域请求一直报错这是前后端分离项目里最高频的问题。报错信息一般是Access-Control-Allow-Origin或者CORS policy。排查顺序是这样的。先看后端是否安装了django-cors-headers并正确配置了中间件。中间件的顺序很关键CorsMiddleware要放在CommonMiddleware之前。然后确认前端请求的URL和Django路由是否匹配如果用了Vite代理先看看代理配置是否生效。有时候报错不是跨域而是404因为代理没匹配上前端请求实际打到了Vite自己的服务器上没有转发到8000端口。还有一个冷门坑是多次OPTIONS预检请求超时。SimpleJWT的TokenRefresh接口偶尔会触发预检错误通常是因为django-cors-headers版本过旧升级到最新版就能解决。6.2 图片和简历文件上传后无法访问开发环境里遇到这个问题多半是media配置没写好。Django处理文件上传需要三个配置MEDIA_URL /media/ MEDIA_ROOT BASE_DIR / media同时要在主urls.py里把media目录暴露出去from django.conf import settings from django.conf.urls.static import static urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)忘记加static这行上传文件时会显示成功但刷新页面后图片URL直接404。这个坑我踩过排查了很久才发现是开发环境静态文件服务没开。6.3 MySQL连接报错或者中文乱码Django连接MySQL最常见的报错是django.db.utils.OperationalError: (1045, Access denied)。检查账号密码是否匹配、MySQL是否允许远程连接。用Navicat或命令行试一下连接数据库确认没问题再排查Django配置。中文乱码一般出现在创建数据库时没指定utf8mb4字符集。创建数据库的语句CREATE DATABASE recruitment DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;如果你已经建了库但发现乱码可以用ALTER DATABASE和ALTER TABLE修改字符集。做毕业设计演示时导师往往会插入测试数据如果乱码影响体验必须提前把字符集统一。6.4 Vue页面刷新后404这个问题的触发场景是部署到Nginx后前端页面第一次访问正常一旦刷新浏览器就404。原因是Vue的history路由模式下刷新时会向服务器请求当前URL对应的文件而Nginx没有对应的物理文件。解决办法是Nginx配置中加入try_files指令让所有非静态资源请求都回退到index.htmllocation / { try_files $uri $uri/ /index.html; }如果实在不想配置Nginx前端也可以改用hash模式路由地址栏会多一个#号但刷新不会404适用于纯演示场景。6.5 数据库表结构变更后运行报错开发过程中肯定会频繁添加字段或者改字段类型最安全的流程是三步走先改models.py然后makemigrations生成迁移文件最后migrate执行迁移。切忌直接改数据库表结构而不同步修改modelsDjango同步数据表靠的是迁移文件不是自动扫描数据库现有结构。如果某次makemigrations后migrate一直报冲突多半是之前生成过同名迁移文件又被你手动删掉了。解决方法是找到各App的migrations目录保留0001_initial.py删除其他迁移文件然后从零开始重新迁移。前提是数据库里的表对你来说无所谓否则别轻易删迁移文件。6.6 PyCharm运行颤振配置类问题PyCharm里常见的一个尴尬场景是终端里python manage.py runserver正常但是在PyCharm里点击运行按钮却报ModuleNotFoundError。这是因为PyCharm运行配置里选择的解释器不是项目虚拟环境。在运行配置的Python Interpreter下拉框里选择venv下的python.exe。如果下拉框里没有就点Add Interpreter选择Existing手动指定虚拟环境的路径。设置好之后再运行就能正常启动Django了。社区版在Vue插件的提示方面弱一些但后端调试是完全没问题的。7. 项目亮点扩展让毕设或作品集更具竞争力校园招聘系统的功能做到上面这些程度已经算一个完整的全栈项目了。但如果想让它在答辩或面试时更有亮点可以再打磨几个方向。一个是加数据可视化。学生投递数据、职位热度、企业活跃度这些数据通过ECharts在前端画成柱状图和饼图。管理员端的Dashboard就有内容可看了后端只需要提供一个统计接口。另一个是引入Excel导入导出。企业HR往往有批量发布职位的需求可以在后台实现一个上传Excel文件批量导入职位的功能。前端用el-upload上传文件后端用openpyxl解析校验字段后逐一创建Job记录。这个功能虽然简单但非常贴近真实企业需求放在项目里是很好的加分项。再一个是从安全角度完善权限控制。目前的后端接口是依靠用户类型判断返回数据的还能进一步细化到对象级别。在DRF视图里重写get_queryset和perform_create确保学生能查看但它不能修改别人的简历企业能管理它的职位但不能篡改其他人的职位。这块考虑得越严谨面试官越容易认可。最后说点个人体会开发校园招聘系统这类全栈项目最大的价值不是代码量有多少而是通过完整地走一遍需求分析、接口设计、前后端联调、部署上线的流程把零散的知识点串成一条线。我最初做的时候Vue刚接触连Vue Router的动态路由都没搞清楚Django也只是照着教程跑通了登录注册。真正把这个项目一块砖一块砖砌起来之后很多似懂非懂的概念才变成真的会了。如果你打算用这个项目做毕业设计或者求职作品最后再给一个实用建议演示前一定准备一份真实的数据哪怕是手动插入的几十条职位和几份简历也比一张全是表格的空界面效果好得多。数据一丰富系统的功能逻辑一眼就能看出来答辩和面试的观感会好很多。希望这篇文章能帮你在做项目时少踩几个坑顺利把它做出来。
返回列表