1. 校园礼服租赁系统项目概述
校园礼服租赁系统是一个基于Python技术栈开发的B/S架构应用,主要解决高校学生在毕业典礼、文艺演出等正式场合的礼服租借需求。我在实际开发中采用了Django作为后端主框架,同时整合了Flask的轻量级特性处理特定模块,前端则使用Vue.js构建响应式界面,开发环境选择了PyCharm专业版。
这个系统的核心价值在于:
- 解决了学生购买礼服使用率低造成的资源浪费问题
- 通过线上预约机制优化了传统线下租赁的排队流程
- 采用多维度礼服管理系统提升了库存周转率
- 为校园活动组织者提供了可视化的礼服调度看板
从技术实现角度看,项目融合了Python生态中两个主流Web框架的优势:Django的ORM和Admin后台为系统提供了稳健的基础架构,而Flask的灵活性则很好地支撑了需要快速迭代的微服务模块。
2. 技术选型与架构设计
2.1 后端框架组合策略
在技术选型阶段,我特别考虑了以下因素:
- 开发效率:Django自带的后台管理系统可以快速搭建礼服管理的基础CRUD功能
- 性能需求:租赁高峰期需要处理并发预约,Flask的轻量级特性更适合实现高并发的API端点
- 团队技能:团队成员对Django更熟悉,但部分复杂业务逻辑用Flask实现更简洁
具体技术栈配置:
# requirements.txt 关键依赖 Django==4.2.6 # 主体框架 Flask==2.3.2 # 微服务模块 django-rest-framework==3.14.0 # API接口 celery==5.3.1 # 异步任务处理2.2 前后端分离架构
系统采用典型的前后端分离模式:
- 前端:Vue 3 + Element Plus构建的管理后台和用户端
- 后端:Django REST framework提供主API,Flask处理支付、短信等独立服务
- 通信:JWT认证 + Axios异步请求
这种架构的优势在礼服租赁场景中尤为明显:
- 前端可以快速响应不同设备的访问需求(特别是移动端预约)
- 后端服务能够按模块独立扩展(如支付模块在毕业季需要更多计算资源)
3. 核心功能模块实现
3.1 礼服库存管理系统
使用Django Model设计礼服数据模型时,我特别注意了以下几个字段:
class Gown(models.Model): STYLE_CHOICES = [ ('B', '学士服'), ('M', '硕士服'), ('D', '博士服'), ('C', '演出服') ] style = models.CharField(max_length=1, choices=STYLE_CHOICES) size = models.CharField(max_length=10) # 支持S-XXL多尺寸 barcode = models.CharField(max_length=20, unique=True) status = models.IntegerField(choices=[ (0, '可租赁'), (1, '已预约'), (2, '清洗中') ]) price_per_day = models.DecimalField(max_digits=6, decimal_places=2) deposit = models.DecimalField(max_digits=6, decimal_places=2) class Meta: indexes = [ models.Index(fields=['style', 'status']), # 高频查询优化 ]库存管理中的几个关键技术点:
- 并发控制:使用select_for_update()解决多人同时预约同一礼服的冲突问题
- 状态追踪:通过状态机模式管理礼服的生命周期(可用→预约中→已租出→归还待洗→可用)
- 清洗调度:利用Celery定时任务自动将超时未归还的礼服标记为异常状态
3.2 租赁业务流程实现
租赁核心流程的代码逻辑:
# views.py @transaction.atomic def create_order(request): # 获取用户选择的礼服列表 gown_ids = request.data.get('gown_ids', []) # 开启数据库事务 try: # 锁定选中的礼服记录 gowns = Gown.objects.filter( id__in=gown_ids, status=0 ).select_for_update() if len(gowns) != len(gown_ids): raise ValidationError("部分礼服已被预订") # 创建订单记录 order = Order.objects.create( user=request.user, total_amount=sum(g.price_per_day for g in gowns) ) # 更新礼服状态 gowns.update(status=1, current_order=order) # 调用支付接口(通过Flask微服务) payment_url = requests.post( FLASK_PAYMENT_SERVICE + '/create', json={'order_id': order.id} ).json()['payment_url'] return Response({'payment_url': payment_url}) except Exception as e: return Response({'error': str(e)}, status=400)业务流程中的关键设计:
- 事务处理:使用Django的@transaction.atomic确保数据一致性
- 支付解耦:将支付流程交给独立的Flask服务处理,避免主应用阻塞
- 状态通知:通过WebSocket实时推送订单状态变更(如清洗完成通知)
4. 混合框架集成方案
4.1 Django与Flask的协同工作
在实际部署中,我采用了两种框架协同工作的方案:
主从模式:
- Django处理核心业务逻辑(用户管理、礼服管理、订单管理)
- Flask运行在独立容器中处理特定功能(支付、短信通知、文件导出)
通信方式:
# Django端调用Flask服务示例 import requests def call_flask_service(data): try: response = requests.post( 'http://flask-service:5000/process', json=data, timeout=5 ) return response.json() except requests.exceptions.RequestException as e: logger.error(f"Flask服务调用失败: {str(e)}") raise ServiceUnavailable("支付服务暂不可用")4.2 共享数据层的处理
两个框架共享数据库时的注意事项:
- 连接池配置:
# settings.py 数据库配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'CONN_MAX_AGE': 600, # 连接复用 'POOL_OPTIONS': { 'max_overflow': 10, 'pool_size': 5 } } }- 会话一致性:
- 使用Redis作为共享会话存储
- 配置相同的SECRET_KEY保证加密一致性
5. 前端Vue.js实现要点
5.1 礼服展示组件设计
采用Vue 3的Composition API实现响应式礼服展示:
<template> <div class="gown-grid"> <div v-for="gown in filteredGowns" :key="gown.id" @click="selectGown(gown)" :class="{ 'selected': isSelected(gown) }"> <img :src="gown.image" :alt="gown.style"> <div class="badge" v-if="gown.status === 1">已预订</div> </div> </div> </template> <script setup> import { computed, ref } from 'vue' const props = defineProps({ gowns: Array, selected: Array }) const filters = ref({ style: '', size: '' }) const filteredGowns = computed(() => { return props.gowns.filter(gown => { return (!filters.value.style || gown.style === filters.value.style) && (!filters.value.size || gown.size === filters.value.size) }) }) </script>5.2 与后端API的交互
使用axios实例封装API请求:
// api.js import axios from 'axios' const api = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000, headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }) // 请求拦截器 api.interceptors.request.use(config => { if (!config.headers.Authorization) { config.headers.Authorization = `Bearer ${localStorage.getItem('token')}` } return config }) // 响应拦截器 api.interceptors.response.use( response => response.data, error => { if (error.response.status === 401) { router.push('/login') } return Promise.reject(error) } ) export const getGowns = (params) => api.get('/gowns', { params }) export const createOrder = (data) => api.post('/orders', data)6. PyCharm开发技巧
6.1 多服务调试配置
在PyCharm中配置复合运行环境:
创建"Django主服务"运行配置:
- 脚本路径:manage.py
- 参数:runserver 0.0.0.0:8000
- 环境变量:DJANGO_SETTINGS_MODULE=config.settings
创建"Flask支付服务"运行配置:
- 脚本路径:payment_service/app.py
- 环境变量:FLASK_ENV=development
使用"Compound"配置同时启动多个服务
6.2 数据库工具的使用技巧
ORM查询优化:
- 使用PyCharm的Django Console快速测试查询语句
- 通过"Explain Query"功能分析SQL执行计划
数据模型可视化:
- 安装"Diagram"插件生成模型关系图
- 使用"View -> Tool Windows -> Database"查看表结构
调试技巧:
- 在视图函数中设置断点时,使用"Evaluate Expression"查看QuerySet结果
- 对复杂查询使用"PyCharm Debugger"的"Step Into My Code"功能
7. 部署与性能优化
7.1 生产环境部署方案
采用Docker Compose编排服务:
version: '3.8' services: django: build: ./django_app ports: - "8000:8000" depends_on: - redis - postgres flask: build: ./flask_service ports: - "5000:5000" nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf redis: image: redis:alpine postgres: image: postgres:13 environment: POSTGRES_PASSWORD: example7.2 高并发场景优化
针对毕业季的流量高峰,我们实施了以下优化措施:
缓存策略:
- 使用Redis缓存热门礼服的查询结果
- 对列表页实施分页缓存
from django.core.cache import cache def get_popular_gowns(): key = 'popular_gowns' result = cache.get(key) if not result: result = Gown.objects.filter(...).values() cache.set(key, result, timeout=60*15) # 15分钟缓存 return result异步任务处理:
- 使用Celery处理耗时的操作(如生成租赁合同PDF)
- 配置RabbitMQ作为消息队列
数据库优化:
- 为高频查询字段添加索引
- 使用select_related/prefetch_related优化关联查询
8. 项目经验与踩坑记录
8.1 多框架集成的教训
会话不一致问题:
- 现象:用户在Django登录后,调用Flask服务时身份验证失败
- 解决方案:统一使用JWT作为认证方式,并在两个服务间共享SECRET_KEY
数据库连接泄漏:
- 现象:Flask服务运行一段时间后出现连接池耗尽
- 修复:为SQLAlchemy配置连接回收
from sqlalchemy import create_engine engine = create_engine( DATABASE_URI, pool_size=5, max_overflow=10, pool_recycle=3600 # 1小时回收连接 )
8.2 业务逻辑的特殊处理
礼服污损赔偿计算:
def calculate_compensation(damage_level, original_price): """ 根据损坏程度计算赔偿金额 :param damage_level: 1-轻微, 2-中等, 3-严重 :param original_price: 礼服原价 :return: 赔偿金额 """ ratios = {1: 0.2, 2: 0.5, 3: 0.8} return original_price * ratios.get(damage_level, 1)超时归还处理:
- 使用Celery Beat定时检查逾期订单
- 自动计算滞纳金(基础费用的20%/天)
9. 扩展功能与未来优化
9.1 智能推荐系统
基于历史租赁数据实现推荐算法:
- 使用协同过滤推荐相似用户选择的礼服
- 根据活动类型推荐合适款式(毕业典礼→学位服,晚会→晚礼服)
9.2 图像识别应用
礼服识别:
- 学生上传自拍照片
- 使用OpenCV识别照片中的礼服款式和编号
- 自动匹配库存记录
尺寸推荐:
- 输入身高体重数据
- 基于历史租赁数据推荐合适尺码
9.3 微信小程序集成
开发微信小程序端的主要考量:
- 利用微信原生API实现扫码租借功能
- 通过微信支付简化支付流程
- 使用订阅消息发送归还提醒
在技术实现上,我保留了Django的后台管理优势,同时将核心API服务迁移到了Flask构建的微服务架构。这种混合模式在项目后期迭代中展现了很好的灵活性——当需要快速实现一个新的支付渠道时,我们可以在不影响主系统的情况下,单独开发和部署一个Flask服务。