1. 项目概述:基于Django的酒店推荐系统设计与实现
这个毕业设计项目采用Python+Django技术栈构建了一套完整的酒店推荐系统。作为全栈开发框架,Django提供了从数据库建模到前端展示的一站式解决方案,特别适合在校学生快速实现具备商业价值的毕业作品。系统核心功能包括用户行为分析、协同过滤推荐算法实现、酒店信息管理三大模块,完整覆盖了推荐系统从数据采集到结果展示的全流程。
我在实际开发中发现,相比其他Python框架,Django的ORM系统能显著降低数据库操作复杂度。例如通过定义Hotel模型类,自动生成的admin后台可直接进行CRUD操作,这对需要快速迭代的毕设项目尤为实用。系统还整合了基于用户的协同过滤算法,通过分析用户历史预订记录计算相似度矩阵,为不同用户生成个性化推荐列表。
提示:选择Django框架时建议使用3.2 LTS版本,这是目前最稳定的长期支持版,能避免因版本兼容性导致的调试问题。
2. 系统架构设计与技术选型
2.1 后端技术栈配置
系统采用经典的MTV模式(Model-Template-View)架构,这是Django区别于其他框架的核心特征。在models.py中定义的数据模型会自动映射到数据库表,例如酒店实体对应的模型包含以下关键字段:
class Hotel(models.Model): name = models.CharField(max_length=100) location = models.PointField() # 使用GeoDjango支持地理位置查询 price_range = models.CharField(max_length=20) amenities = models.ManyToManyField('Amenity') rating = models.FloatField(default=0)数据库选用PostgreSQL而非默认的SQLite,主要考虑三点:一是支持地理空间查询扩展PostGIS,便于实现"附近酒店"功能;二是生产环境适配性更好;三是处理大规模用户行为数据时性能更优。配置时需要在settings.py中添加:
DATABASES = { 'default': { 'ENGINE': 'django.contrib.gis.db.backends.postgis', 'NAME': 'hotel_rec', 'USER': 'postgres', 'PASSWORD': 'yourpassword', 'HOST': 'localhost' } }2.2 推荐算法实现细节
系统采用混合推荐策略,结合基于内容的过滤和协同过滤两种方法。核心算法模块位于recommender/algorithms.py中,主要包含以下函数:
- 用户相似度计算:使用修正余弦相似度处理稀疏评分矩阵
def cosine_similarity(user1, user2): # 获取共同评分项 common_hotels = set(user1.ratings.keys()) & set(user2.ratings.keys()) if not common_hotels: return 0 # 计算向量点积和模长 dot_product = sum(user1.ratings[h] * user2.ratings[h] for h in common_hotels) norm1 = sqrt(sum(r**2 for r in user1.ratings.values())) norm2 = sqrt(sum(r**2 for r in user2.ratings.values())) return dot_product / (norm1 * norm2)- 预测评分生成:根据相似用户加权平均预测目标用户对未评分酒店的偏好
def predict_rating(target_user, hotel, k_neighbors=5): similarities = [] for user in all_users: if user != target_user and hotel in user.ratings: sim = cosine_similarity(target_user, user) similarities.append((sim, user.ratings[hotel])) # 取相似度最高的k个邻居 similarities.sort(reverse=True) top_k = similarities[:k_neighbors] if not top_k: return hotel.average_rating # 退回全局平均分 weighted_sum = sum(sim * rating for sim, rating in top_k) sum_sim = sum(sim for sim, _ in top_k) return weighted_sum / sum_sim注意:实际部署时应考虑算法性能优化,对于大规模用户数据集,建议使用Redis缓存相似度矩阵或改用矩阵分解等更高效算法。
3. 关键功能模块实现
3.1 用户认证与权限管理
系统采用Django内置的auth系统实现用户管理,通过扩展AbstractUser类添加用户画像字段:
from django.contrib.auth.models import AbstractUser class User(AbstractUser): GENDER_CHOICES = [('M','Male'),('F','Female'),('O','Other')] age = models.PositiveIntegerField(null=True) gender = models.CharField(max_length=1, choices=GENDER_CHOICES) preference_tags = models.ManyToManyField('Tag') def get_similar_users(self, n=5): """找到最相似的n个用户用于推荐""" # 实现逻辑参考2.2节算法视图层使用LoginRequiredMixin和PermissionRequiredMixin实现权限控制:
from django.contrib.auth.mixins import LoginRequiredMixin class RecommendationView(LoginRequiredMixin, generic.ListView): model = Hotel template_name = 'recommendation/list.html' def get_queryset(self): # 调用推荐算法获取结果 return get_recommendations(self.request.user)3.2 酒店数据采集与处理
系统支持两种数据来源:
- 人工录入:通过Django Admin后台添加
- API导入:编写管理命令从公开旅游平台抓取数据
创建数据采集命令示例:
from django.core.management.base import BaseCommand import requests class Command(BaseCommand): help = 'Import hotel data from external API' def handle(self, *args, **options): url = "https://api.travel.com/hotels" response = requests.get(url) data = response.json() for item in data['results']: Hotel.objects.update_or_create( external_id=item['id'], defaults={ 'name': item['name'], 'location': fromstr(f"POINT({item['lng']} {item['lat']})"), # 其他字段映射... } )运行方式:python manage.py import_hotels
4. 系统部署与调试技巧
4.1 开发环境配置
推荐使用VSCode作为开发环境,关键插件包括:
- Python:提供语法高亮和调试支持
- Django:模板语法支持和快捷命令
- SQLite:可视化数据库操作
- GitLens:版本控制管理
调试配置(.vscode/launch.json)示例:
{ "version": "0.2.0", "configurations": [ { "name": "Django", "type": "python", "request": "launch", "program": "${workspaceFolder}/manage.py", "args": ["runserver"], "django": true } ] }4.2 生产环境部署
使用Nginx+Gunicorn部署方案,关键步骤:
- 安装依赖:
pip install gunicorn psycopg2-binary- 创建Gunicorn服务文件(/etc/systemd/system/gunicorn.service):
[Unit] Description=gunicorn daemon After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/path/to/your/project ExecStart=/path/to/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/tmp/hotel_rec.sock core.wsgi:application [Install] WantedBy=multi-user.target- Nginx配置片段:
server { listen 80; server_name yourdomain.com; location /static/ { alias /path/to/static/files; } location / { include proxy_params; proxy_pass http://unix:/tmp/hotel_rec.sock; } }4.3 常见问题排查
静态文件404错误:
- 确保执行了
collectstatic命令 - 检查Nginx配置中的alias路径是否正确
- 确认STATIC_ROOT和STATIC_URL设置
- 确保执行了
数据库连接问题:
- PostgreSQL需要额外安装libpq-dev:
sudo apt-get install libpq-dev - 检查settings.py中的HOST是否允许远程连接
- 测试纯Python环境能否连接:
import psycopg2; conn = psycopg2.connect("dbname='hotel_rec' user='postgres'")
- PostgreSQL需要额外安装libpq-dev:
推荐结果不稳定:
- 检查用户行为数据是否足够(冷启动问题)
- 尝试调整相似度计算中的k值
- 考虑加入时间衰减因子,更重视近期行为
我在实际部署中发现,当用户量超过1万时,原生Python实现的协同过滤算法会出现性能瓶颈。这时可以考虑以下优化方案:
- 使用Django的cache框架缓存相似度矩阵
- 将计算密集型任务迁移到Celery异步任务队列
- 改用Surprise或LightFM等专业推荐系统库