Flask+Vue房屋租赁系统开发实战
1. 项目概述:基于Flask+Vue的房屋租赁系统开发
房屋租赁市场近年来持续升温,无论是长租公寓还是短租民宿,都需要高效的管理系统支撑业务运转。这套基于Python Flask后端和Vue前端的技术方案,完美解决了传统租赁管理中的三大痛点:数据分散难统计、人工操作效率低、租户体验差。
我选择PyCharm作为开发IDE主要考虑其强大的Python和JavaScript双向支持能力,社区版完全免费且自带Vue.js插件。Django虽然同属Python生态,但Flask的轻量级特性更适合快速迭代的租赁系统开发——不需要Django那些内置的admin、auth等重型组件,我们可以按需引入扩展库。
2. 技术栈选型解析
2.1 后端技术组合
Flask+SQLAlchemy构成核心后端架构:
# 典型Flask应用结构 app/ ├── __init__.py ├── models/ # SQLAlchemy数据模型 │ ├── tenant.py # 租户模型 │ └── contract.py # 合同模型 ├── routes/ # 业务路由 │ ├── auth.py # 认证接口 │ └── payment.py # 支付接口 └── config.py # 多环境配置选择Flask而非Django的关键考量:
- 租赁业务模型需要高度定制化,Django的ORM预设字段反成约束
- 支付、合同等模块更新频繁,Flask的蓝图机制更利于模块化开发
- 需要混用MySQL和Redis时,Flask的扩展集成更灵活
2.2 前端技术方案
Vue 3组合式API大幅提升开发效率:
// 合同管理组件示例 <script setup> import { ref } from 'vue' const searchQuery = ref('') const contracts = ref([]) const loadContracts = async () => { const res = await axios.get('/api/contracts', { params: { q: searchQuery.value } }) contracts.value = res.data } </script>特别采用Vue-Router实现多级路由,匹配租赁业务场景:
const routes = [ { path: '/contract', component: Layout, children: [ { path: 'create', component: ContractCreate }, { path: ':id/payment', component: PaymentHistory } ] } ]3. 核心功能实现细节
3.1 房源管理模块
数据库设计采用多表关联结构:
class House(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100)) # 其他字段... class HouseImage(db.Model): id = db.Column(db.Integer, primary_key=True) url = db.Column(db.String(255)) house_id = db.Column(db.Integer, db.ForeignKey('house.id'))图片上传采用Flask-Reuploaded扩展:
from flask_uploads import UploadSet, configure_uploads photos = UploadSet('photos', IMAGES) app.config['UPLOADED_PHOTOS_DEST'] = 'static/uploads' configure_uploads(app, photos) @app.route('/upload', methods=['POST']) def upload(): filename = photos.save(request.files['image']) return {'url': url_for('static', filename=f'uploads/{filename}')}3.2 在线签约系统
合同PDF生成使用ReportLab库:
def generate_contract_pdf(contract_data): buffer = BytesIO() p = canvas.Canvas(buffer) # 绘制合同标题 p.setFont("Helvetica-Bold", 16) p.drawString(100, 800, "房屋租赁合同") # 绘制合同内容 p.setFont("Helvetica", 12) y_position = 750 for clause in contract_data['clauses']: p.drawString(100, y_position, clause) y_position -= 20 p.showPage() p.save() buffer.seek(0) return buffer电子签名采用Canvas绘图技术:
<template> <canvas ref="signaturePad" @mousedown="startDrawing" @mousemove="draw" @mouseup="endDrawing"> </canvas> </template> <script> export default { methods: { startDrawing(e) { const canvas = this.$refs.signaturePad const ctx = canvas.getContext('2d') ctx.beginPath() ctx.moveTo(e.offsetX, e.offsetY) this.isDrawing = true }, draw(e) { if (!this.isDrawing) return const ctx = this.$refs.signaturePad.getContext('2d') ctx.lineTo(e.offsetX, e.offsetY) ctx.stroke() } } } </script>4. 前后端协同开发实践
4.1 接口规范设计
采用RESTful风格设计API:
GET /api/houses - 获取房源列表 POST /api/houses - 新建房源 GET /api/houses/:id - 获取房源详情 PUT /api/houses/:id - 更新房源 DELETE /api/houses/:id - 删除房源响应统一格式:
{ "code": 200, "message": "success", "data": { /* 业务数据 */ } }4.2 跨域解决方案
Flask端配置CORS:
from flask_cors import CORS app = Flask(__name__) CORS(app, resources={ r"/api/*": { "origins": ["http://localhost:8080"], "methods": ["GET", "POST", "PUT", "DELETE"], "allow_headers": ["Content-Type", "Authorization"] } })Axios请求封装示例:
const service = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000 }) // 请求拦截器 service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 响应拦截器 service.interceptors.response.use( response => { if (response.data.code !== 200) { return Promise.reject(response.data.message) } return response.data.data }, error => { return Promise.reject(error) } )5. 开发环境配置指南
5.1 PyCharm专业配置
- 启用Vue.js插件:File > Settings > Plugins 搜索Vue.js安装
- 配置Python解释器:建议使用venv虚拟环境
- 运行配置:设置FLASK_APP环境变量为app.py
调试配置示例:
{ "name": "Flask", "type": "python", "request": "launch", "module": "flask", "env": { "FLASK_APP": "app.py", "FLASK_ENV": "development" }, "args": ["run", "--no-debugger"] }5.2 数据库迁移方案
使用Flask-Migrate管理数据库变更:
# 初始化迁移仓库 flask db init # 生成迁移脚本 flask db migrate -m "create house table" # 执行迁移 flask db upgrade迁移文件示例:
def upgrade(): op.create_table( 'house', sa.Column('id', sa.Integer(), nullable=False), sa.Column('title', sa.String(length=100), nullable=False), sa.PrimaryKeyConstraint('id') )6. 部署上线关键步骤
6.1 生产环境配置
Nginx配置示例:
server { listen 80; server_name yourdomain.com; location /api { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; } location / { root /path/to/vue/dist; try_files $uri $uri/ /index.html; } }使用Gunicorn运行Flask应用:
gunicorn -w 4 -b 127.0.0.1:5000 app:app6.2 性能优化技巧
- Redis缓存热门房源:
from flask_redis import FlaskRedis redis = FlaskRedis(app) @app.route('/houses/hot') def hot_houses(): cache_key = 'hot_houses' data = redis.get(cache_key) if data: return jsonify(json.loads(data)) houses = db.session.query(House).order_by(House.view_count.desc()).limit(10).all() result = [h.to_dict() for h in houses] redis.setex(cache_key, 3600, json.dumps(result)) # 缓存1小时 return jsonify(result)- Vue组件懒加载:
const ContractDetail = () => import('./views/ContractDetail.vue')7. 典型问题排查实录
7.1 跨域Cookie失效问题
现象:前端无法携带认证Cookie 解决方案:
CORS(app, supports_credentials=True)前端axios配置:
axios.defaults.withCredentials = true7.2 Vue路由刷新404
配置Nginx重定向:
location / { try_files $uri $uri/ /index.html; }7.3 Flask静态文件冲突
避免与Vue静态资源冲突:
app = Flask(__name__, static_folder=None)8. 项目扩展方向建议
- 微信小程序端:使用uni-app框架复用Vue代码
- 智能合约:将租赁合同上链存证
- 数据分析:使用Pandas生成租金收益报表
- 物联网集成:对接智能门锁API
这套技术栈在开发过程中展现出极佳的灵活性。Flask的轻量特性让我们能快速响应业务变化,Vue的组件化开发则大幅提升了前端复用率。特别在合同管理模块,通过PDF生成+电子签名的组合方案,将原本需要3天处理的签约流程缩短至20分钟。
