1. 项目概述:Python+Vue学生实习信息管理系统
这个系统是我去年为某高校就业指导中心开发的一套实习管理平台,主要解决学生实习过程中信息分散、管理低效的问题。传统Excel表格管理方式已经无法满足3000多名学生的实习跟踪需求,经常出现信息更新不及时、统计困难等问题。
系统采用前后端分离架构,后端使用Python+Django处理业务逻辑和数据存储,前端用Vue.js构建交互界面。选择这套技术栈主要基于三点考虑:一是Python+Django的开发效率高,适合快速迭代;二是Vue的组件化开发能很好应对复杂表单场景;三是两者都有丰富的生态支持,遇到问题容易找到解决方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能模块设计
2.1 学生端功能实现
学生端采用Vue CLI搭建,主要包含以下功能模块:
- 实习申请模块:
vue复制<template>
<div class="application-form">
<el-form :model="form" :rules="rules" ref="formRef">
<el-form-item label="实习单位" prop="company">
<el-input v-model="form.company" />
</el-form-item>
<el-form-item label="开始日期" prop="startDate">
<el-date-picker v-model="form.startDate" type="date" />
</el-form-item>
<!-- 更多表单字段 -->
</el-form>
</div>
</template>
关键点在于表单验证逻辑的处理,我们使用了Element UI的表单验证机制,结合自定义校验规则:
javascript复制rules: {
company: [
{ required: true, message: '请输入实习单位名称', trigger: 'blur' },
{ min: 2, max: 50, message: '长度在2到50个字符', trigger: 'blur' }
],
startDate: [
{ type: 'date', required: true, message: '请选择开始日期', trigger: 'change' }
]
}
2.2 教师审核后台开发
后端使用Django REST framework构建API,核心模型设计如下:
python复制class Internship(models.Model):
STATUS_CHOICES = (
('pending', '待审核'),
('approved', '已通过'),
('rejected', '已拒绝')
)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
company = models.CharField(max_length=100)
start_date = models.DateField()
end_date = models.DateField()
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_at']
审核接口实现示例:
python复制class InternshipApprovalView(APIView):
permission_classes = [IsTeacher]
def post(self, request, pk):
internship = get_object_or_404(Internship, pk=pk)
serializer = InternshipApprovalSerializer(data=request.data)
if serializer.is_valid():
internship.status = serializer.validated_data['status']
internship.save()
return Response({'status': 'success'})
return Response(serializer.errors, status=400)
3. 关键技术实现细节
3.1 前后端数据交互方案
采用JWT认证方式,Django端配置:
python复制REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
Vue端封装axios请求:
javascript复制const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
service.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
}
return config
},
error => {
return Promise.reject(error)
}
)
3.2 文件导出功能实现
实习报表导出采用Python的openpyxl库:
python复制from openpyxl import Workbook
from django.http import HttpResponse
def export_internships(request):
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="internships.xlsx"'
wb = Workbook()
ws = wb.active
ws.title = "实习信息"
# 添加表头
headers = ['学号', '姓名', '实习单位', '开始日期', '结束日期', '状态']
ws.append(headers)
# 添加数据
internships = Internship.objects.select_related('student').all()
for item in internships:
ws.append([
item.student.id,
item.student.name,
item.company,
item.start_date.strftime('%Y-%m-%d'),
item.end_date.strftime('%Y-%m-%d'),
item.get_status_display()
])
wb.save(response)
return response
4. 系统部署方案
4.1 生产环境配置
使用Nginx+Docker部署方案,docker-compose.yml配置示例:
yaml复制version: '3'
services:
backend:
build: ./backend
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./backend:/app
ports:
- "8000:8000"
depends_on:
- db
frontend:
build: ./frontend
volumes:
- ./frontend:/app
ports:
- "8080:8080"
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Nginx配置要点:
nginx复制server {
listen 80;
server_name example.com;
location /api {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
}
location / {
root /var/www/frontend/dist;
try_files $uri $uri/ /index.html;
}
}
5. 开发中的经验总结
5.1 性能优化实践
- 数据库查询优化:
python复制# 错误做法:N+1查询问题
internships = Internship.objects.all()
for item in internships:
print(item.student.name) # 每次循环都会查询数据库
# 正确做法:使用select_related
internships = Internship.objects.select_related('student').all()
- 前端懒加载:
vue复制<template>
<div>
<el-table :data="tableData" v-loading="loading">
<!-- 表格列定义 -->
</el-table>
<el-pagination
@current-change="handlePageChange"
:current-page="currentPage"
:page-size="pageSize"
:total="total">
</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
tableData: [],
loading: false
}
},
methods: {
async fetchData() {
this.loading = true
const res = await getInternships({
page: this.currentPage,
size: this.pageSize
})
this.tableData = res.data.items
this.total = res.data.total
this.loading = false
}
}
}
</script>
5.2 常见问题排查
- 跨域问题解决方案:
python复制# Django后端配置
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
]
CORS_ORIGIN_WHITELIST = [
'http://localhost:8080',
'https://yourdomain.com'
]
- Vue路由刷新404问题:
javascript复制// nginx配置需要添加
location / {
try_files $uri $uri/ /index.html;
}
- 静态文件收集问题:
python复制# settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# 执行收集命令
python manage.py collectstatic
这个项目从需求分析到上线部署共耗时2个月,期间最大的收获是深入理解了前后端分离架构的实际应用。特别是在处理批量数据导入导出时,通过使用Python的Pandas库优化处理逻辑,将原本需要几分钟的操作优化到秒级完成
