1. 项目概述
这个基于Python-Django的实习招聘系统是我去年为一个高校就业指导中心开发的实际项目。当时学校面临一个痛点:传统的邮件+Excel表格的招聘管理方式效率低下,企业发布岗位和学生投递简历都极为不便。我们团队用3个月时间完成了这套系统的开发上线,目前已经稳定运行一年多,日均处理300+份简历投递。
系统采用经典的MVC架构,前端使用Bootstrap+JavaScript实现响应式布局,后端基于Django框架搭建。数据库选用MySQL,同时配合Redis做缓存优化。整个系统包含企业端、学生端和管理后台三个模块,实现了从岗位发布、简历投递到面试管理的全流程数字化。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能设计
2.1 用户权限体系
系统采用Django内置的auth模块进行扩展,构建了三级权限体系:
python复制class User(AbstractUser):
USER_TYPE_CHOICES = (
(1, 'admin'),
(2, 'company'),
(3, 'student'),
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
# 企业用户额外字段
company_name = models.CharField(max_length=100, blank=True)
# 学生用户额外字段
student_id = models.CharField(max_length=20, blank=True)
权限控制通过自定义装饰器实现:
python复制def company_required(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated or request.user.user_type != 2:
return HttpResponseForbidden()
return view_func(request, *args, **kwargs)
return _wrapped_view
2.2 岗位管理模块
企业用户可以发布、编辑和关闭招聘岗位。核心模型设计如下:
python复制class JobPost(models.Model):
STATUS_CHOICES = (
('open', '招聘中'),
('closed', '已结束'),
)
title = models.CharField(max_length=100)
description = models.TextField()
requirements = models.TextField()
company = models.ForeignKey(User, on_delete=models.CASCADE)
publish_date = models.DateTimeField(auto_now_add=True)
deadline = models.DateTimeField()
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='open')
# 使用Django信号自动关闭过期岗位
@receiver(post_save, sender=JobPost)
def update_job_status(sender, instance, **kwargs):
if instance.deadline < timezone.now():
instance.status = 'closed'
instance.save()
2.3 简历投递系统
学生用户可以上传简历文件(支持PDF/DOCX格式)并关联到具体岗位:
python复制def validate_file_extension(value):
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.pdf', '.docx']
if not ext.lower() in valid_extensions:
raise ValidationError('仅支持PDF和DOCX格式')
class Application(models.Model):
job = models.ForeignKey(JobPost, on_delete=models.CASCADE)
student = models.ForeignKey(User, on_delete=models.CASCADE)
resume = models.FileField(upload_to='resumes/', validators=[validate_file_extension])
apply_time = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=20, default='pending')
文件存储使用Django的FileSystemStorage,并配置了Nginx直接提供静态文件服务,减轻Django服务器负担。
3. 关键技术实现
3.1 高性能查询优化
面对大量岗位列表查询,我们采用了以下优化措施:
- 使用
select_related和prefetch_related减少数据库查询次数 - 对高频访问的首页岗位列表实现Redis缓存
- 添加数据库索引:
python复制class Meta:
indexes = [
models.Index(fields=['status', 'publish_date']),
models.Index(fields=['company']),
]
缓存配置示例:
python复制CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
3.2 安全防护措施
-
文件上传安全:
- 使用Django的
FileExtensionValidator限制文件类型 - 上传文件重命名处理
- 设置Nginx限制最大上传大小
- 使用Django的
-
XSS防护:
- 模板层自动转义:
{{ content|escape }} - 使用Django的
mark_safe谨慎处理可信HTML
- 模板层自动转义:
-
CSRF防护:
- 确保所有表单包含
{% csrf_token %} - 配置严格的CORS策略
- 确保所有表单包含
3.3 实时通知系统
使用Django Channels实现WebSocket通知:
python复制# consumers.py
class NotificationConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope['user']
await self.channel_layer.group_add(
f"notifications_{self.user.id}",
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
f"notifications_{self.user.id}",
self.channel_name
)
async def send_notification(self, event):
await self.send(text_data=json.dumps(event['message']))
4. 部署方案
我们采用Docker+Nginx+Gunicorn的生产级部署方案:
dockerfile复制# Dockerfile
FROM python:3.9
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
Nginx配置关键部分:
nginx复制server {
listen 80;
server_name recruit.example.com;
location /static/ {
alias /code/staticfiles/;
}
location /media/ {
alias /code/media/;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
使用Gunicorn启动:
bash复制gunicorn --workers 4 --bind 0.0.0.0:8000 config.wsgi
5. 开发经验分享
5.1 Django项目结构优化
推荐的项目结构:
code复制recruit_system/
├── config/ # 项目配置
├── apps/ # 自定义应用
│ ├── account/ # 用户相关
│ ├── job/ # 岗位管理
│ └── application/ # 简历投递
├── static/ # 静态文件
├── templates/ # 模板文件
└── manage.py
使用python manage.py startapp创建应用后,将其移动到apps目录,并修改settings.py:
python复制import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
5.2 调试技巧
- 使用Django Debug Toolbar分析性能瓶颈
- 配置日志记录:
python复制LOGGING = {
'version': 1,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
},
},
}
- 使用
django-extensions的runserver_plus支持远程调试
5.3 常见问题解决
-
静态文件404问题:
- 确保
DEBUG=False时运行collectstatic - 检查Nginx配置中的静态文件路径
- 确保
-
数据库连接超时:
- 配置连接池:
python复制'OPTIONS': { 'CONN_MAX_AGE': 300, }
- 配置连接池:
-
时区问题:
- 统一使用UTC时间存储
- 前端展示时转换为本地时区
6. 项目扩展方向
-
智能匹配功能:
- 使用NLP技术分析简历和岗位描述的匹配度
- 实现基于技能的推荐系统
-
数据分析看板:
- 使用Django REST Framework构建API
- 配合Vue.js实现动态数据可视化
-
移动端适配:
- 开发React Native应用
- 或使用PWA技术实现离线功能
这个项目让我深刻体会到Django作为全功能框架的强大之处。它的"batteries-included"理念让我们能够快速实现业务需求,同时保持代码的可维护性。特别是在用户认证、后台管理这些常见功能上,Django提供了开箱即用的解决方案,大大缩短了开发周期。
