用Flask+Bootstrap手把手教你从零搭建一个智能租房网站(附完整源码)

张开发
2026/4/20 19:06:43 15 分钟阅读

分享文章

用Flask+Bootstrap手把手教你从零搭建一个智能租房网站(附完整源码)
从零构建智能租房平台FlaskBootstrap全栈开发实战最近两年身边不少朋友开始尝试用Python做副业项目而Web开发始终是最容易落地的方向之一。作为一个从Django转战Flask的开发者我深刻体会到Flask微框架的魅力——它就像乐高积木用最精简的核心理念给你充分的创造自由。今天我们就用这个不足千行代码的框架配合Bootstrap前端工具包打造一个带数据可视化功能的智能租房平台。这个项目特别适合已经掌握Python基础语法但尚未接触过完整Web开发流程的学习者。不同于网上那些只教片段代码的教程我们会从虚拟环境配置开始逐步实现用户系统、数据库交互、前后端数据绑定等核心功能最终完成一个具备房源推荐算法的实战项目。所有代码都经过真实数据测试你可以在文章末尾获取完整项目源码。1. 开发环境与项目初始化1.1 工具链选择工欲善其事必先利其器。虽然理论上用记事本也能写代码但合适的工具能提升数倍效率# 基础环境 Python 3.8 # 建议3.8-3.10稳定版本 pip 23.0 # 新版依赖解析更可靠 # 开发工具推荐组合 VS Code Python插件 # 轻量级首选 PyCharm专业版 # 对Web开发支持更完善我强烈建议使用虚拟环境隔离项目依赖这是避免依赖地狱的最佳实践# 创建虚拟环境Windows python -m venv venv venv\Scripts\activate # 安装核心依赖 pip install flask2.3.2 pip install flask-sqlalchemy3.0.3 pip install flask-wtf1.1.11.2 项目骨架搭建Flask项目的目录结构看似自由但合理的组织能大幅降低后期维护成本。这是我们采用的MVTModel-View-Template结构/smart_rental │── /static # 静态资源 │ ├── /css # Bootstrap自定义样式 │ ├── /js # ECharts等前端库 │ └── /images # 房源缩略图 │── /templates # Jinja2模板 │ ├── base.html # 基础模板 │ └── /partials # 组件片段 │── /models # 数据模型 │── /routes # 视图路由 │── config.py # 配置文件 │── app.py # 应用入口 └── requirements.txt # 依赖清单提示使用flask --app app run --debug启动开发服务器时添加--debug参数会开启自动重载和调试模式修改代码后无需手动重启服务。2. 数据建模与数据库设计2.1 实体关系分析租房平台的核心数据关系可以抽象为三个主要实体用户(User)注册登录、收藏行为房源(House)基础信息、价格走势小区(Community)地理位置、周边配套它们之间的关系通过SQLAlchemy的ORM系统实现# models/house.py class House(db.Model): __tablename__ houses id db.Column(db.Integer, primary_keyTrue) title db.Column(db.String(100), nullableFalse) price db.Column(db.Float) area db.Column(db.Float) # 建筑面积 floor db.Column(db.String(20)) # 楼层信息 # 外键关系 community_id db.Column(db.Integer, db.ForeignKey(communities.id)) user_id db.Column(db.Integer, db.ForeignKey(users.id)) # 关系属性 images db.relationship(HouseImage, backrefhouse) favorites db.relationship(Favorite, backrefhouse)2.2 数据库迁移配置使用Flask-Migrate实现数据库版本控制# app.py from flask_migrate import Migrate app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///smart_rental.db db.init_app(app) migrate Migrate(app, db)执行迁移命令生成数据库flask db init # 首次运行 flask db migrate # 生成迁移脚本 flask db upgrade # 执行迁移3. 前端界面与模板设计3.1 Bootstrap布局技巧利用Bootstrap 5的网格系统构建响应式布局!-- templates/base.html -- div classcontainer-fluid div classrow min-vh-100 !-- 侧边导航 -- div classcol-md-3 col-lg-2 bg-light px-0 {% include partials/sidebar.html %} /div !-- 主内容区 -- main classcol-md-9 col-lg-10 px-4 {% block content %}{% endblock %} /main /div /div3.2 Jinja2模板继承通过模板继承避免重复代码!-- templates/list.html -- {% extends base.html %} {% block content %} div classrow row-cols-1 row-cols-md-3 g-4 {% for house in houses %} div classcol div classcard h-100 shadow-sm img src{{ url_for(static, filenamehouse.images[0].path) }} classcard-img-top alt{{ house.title }} div classcard-body h5 classcard-title{{ house.title }}/h5 p classtext-danger fs-4{{ house.price }}万/p /div /div /div {% endfor %} /div {% endblock %}4. 核心功能实现4.1 用户认证系统使用Flask-Login管理用户会话# routes/auth.py from flask_login import login_user, logout_user bp.route(/login, methods[POST]) def login(): form LoginForm() if form.validate_on_submit(): user User.query.filter_by(emailform.email.data).first() if user and user.check_password(form.password.data): login_user(user, rememberform.remember.data) return redirect(url_for(main.index)) return render_template(auth/login.html, formform)密码安全处理采用Werkzeug的加密工具# models/user.py from werkzeug.security import generate_password_hash, check_password_hash class User(db.Model): # ... def set_password(self, password): self.password_hash generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)4.2 智能推荐算法基于用户行为的简易推荐逻辑# utils/recommend.py def recommend_houses(user): # 获取用户收藏的小区ID fav_communities {f.house.community_id for f in user.favorites} # 基础推荐同小区其他房源 query House.query.filter( House.community_id.in_(fav_communities), House.id.notin_([f.house_id for f in user.favorites]) ) # 价格区间浮动10% if user.preferred_price: min_price user.preferred_price * 0.9 max_price user.preferred_price * 1.1 query query.filter(House.price.between(min_price, max_price)) return query.order_by(House.created_at.desc()).limit(6)5. 数据可视化实现5.1 ECharts集成在详情页展示户型价格分布// static/js/charts.js function initPriceChart(data) { const chart echarts.init(document.getElementById(price-chart)); const option { tooltip: { trigger: axis }, xAxis: { type: category, data: data.xAxis }, yAxis: { type: value }, series: [{ data: data.series, type: line, smooth: true, areaStyle: {} }] }; chart.setOption(option); }5.2 后端数据接口提供JSON格式的图表数据# routes/house.py bp.route(/int:id/price-trend) def price_trend(id): house House.query.get_or_404(id) # 模拟价格数据 - 实际项目应从数据库查询 data { xAxis: [1月, 2月, 3月, 4月, 5月], series: [ house.price * 0.95, house.price * 0.97, house.price, house.price * 1.02, house.price * 1.05 ] } return jsonify(data)6. 项目部署与优化6.1 生产环境配置使用Waitress作为WSGI服务器# wsgi.py from waitress import serve from app import create_app app create_app() serve(app, host0.0.0.0, port5000)6.2 性能优化技巧数据库查询优化示例# 低效写法 houses House.query.all() for house in houses: print(house.community.name) # 产生N1查询问题 # 优化写法 - 使用join预加载 houses House.query.options(db.joinedload(House.community)).all()7. 常见问题解决方案Q表单提交后页面刷新导致重复提交A使用Post/Redirect/Get模式bp.route(/create, methods[POST]) def create(): form HouseForm() if form.validate_on_submit(): house House() form.populate_obj(house) db.session.add(house) db.session.commit() flash(房源发布成功, success) return redirect(url_for(house.detail, idhouse.id)) # 关键重定向 return render_template(house/create.html, formform)Q静态文件修改后浏览器缓存不更新A在url_for中添加版本参数link href{{ url_for(static, filenamecss/main.css, v1.0) }} relstylesheet这个项目我从最初的原型到最终上线用了三周时间期间最大的收获不是技术层面的突破而是对简单设计的理解。Flask的简洁哲学教会我在每个功能实现前先问这个需求真的需要复杂实现吗比如推荐算法最初版本只有20行代码但用户满意度反而比后来尝试的复杂模型更高。

更多文章