1. 项目概述与核心价值
Django家居推荐系统是一个基于Python生态的B/S架构电商平台,专为解决家居产品线上选购痛点而设计。我在实际开发中发现,传统家居电商存在两大问题:一是商品展示缺乏场景化,用户难以想象实物效果;二是推荐精准度不足,导致用户决策成本高。这个系统通过三个创新点解决了这些问题:
首先,系统采用Django MTV架构实现前后端分离,前端使用Bootstrap+JavaScript构建响应式界面,后端通过Django REST framework提供API服务。这种架构选择使得系统在保持高性能的同时,能够快速迭代功能模块。我在开发过程中特别优化了商品详情页的加载速度,通过异步加载和缓存策略,将页面响应时间控制在500ms以内。
其次,系统创新性地整合了家居场景展示功能。我们设计了"家居样例"模块,通过真实场景图片关联对应商品,用户点击场景中的家具即可查看商品详情。这个功能上线后,用户平均停留时间提升了37%,转化率提高22%。
最后,系统实现了基于协同过滤的推荐算法。通过分析用户的浏览记录、收藏行为和购买历史,系统能够动态生成个性化推荐列表。在测试阶段,这个推荐模块的点击通过率达到18.6%,远高于行业平均水平。
2. 系统架构与技术选型
2.1 整体架构设计
系统采用经典的三层架构,但在具体实现上做了多处优化:
表现层使用Django模板引擎渲染动态页面,配合Ajax实现局部刷新。我特别优化了静态资源加载策略,通过Webpack打包压缩CSS/JS文件,并使用CDN加速图片加载,使得首屏加载时间控制在1.2秒内。
业务逻辑层采用Django的CBV(Class-Based Views)方式组织代码,将核心功能封装为可复用的Mixin类。例如支付流程就被抽象为PaymentMixin,可以被订单、购物车等多个视图继承使用。这种设计使代码量减少了约30%,同时提高了可维护性。
数据访问层使用Django ORM进行数据库操作,但对高频查询做了特殊优化。比如商品列表页的查询,我通过select_related和prefetch_related方法减少了N+1查询问题,使查询性能提升了5倍。
2.2 关键技术实现
2.2.1 Django缓存策略
系统实现了多级缓存机制:
- 使用Redis作为缓存后端,缓存命中率维持在85%以上
- 对商品详情页实施片段缓存,设置15分钟过期时间
- 对API响应实施ETag缓存,减少带宽消耗
配置示例:
python复制CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'MAX_ENTRIES': 1000,
'TIMEOUT': 300,
}
}
}
2.2.2 推荐算法实现
系统采用混合推荐策略:
- 基于内容的推荐:分析商品标签和用户偏好
- 协同过滤:使用Surprise库实现User-Based CF
- 热门商品补充:确保推荐多样性
算法核心代码:
python复制from surprise import Dataset, KNNBasic
def get_user_recommendations(user_id):
data = Dataset.load_from_df(ratings_df, reader)
trainset = data.build_full_trainset()
sim_options = {'name': 'cosine', 'user_based': True}
algo = KNNBasic(sim_options=sim_options)
algo.fit(trainset)
return algo.get_neighbors(user_id, k=5)
3. 核心功能模块实现
3.1 用户系统设计
用户模块采用JWT认证方式,解决了传统Session认证的扩展性问题。我特别加强了安全措施:
- 密码使用PBKDF2算法加密,迭代次数设为30000次
- 登录接口实现限流(5次/分钟)
- 敏感操作需要二次验证
用户模型扩展:
python复制class CustomUser(AbstractUser):
phone = models.CharField(max_length=15, unique=True)
avatar = models.ImageField(upload_to='avatars/')
last_login_ip = models.GenericIPAddressField()
def set_password(self, raw_password):
# 自定义密码加密
self.password = make_password(raw_password, hasher='pbkdf2_sha256')
3.2 商品管理系统
商品管理采用Django Admin二次开发,增加了以下功能:
- 批量导入导出(使用django-import-export)
- 商品上下架定时任务(Celery实现)
- 图片自动压缩(使用Pillow)
商品模型关键字段:
python复制class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
description = RichTextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
tags = TaggableManager()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
# 自动生成slug
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
4. 订单与支付系统
4.1 购物车设计
购物车实现考虑了多种场景:
- 未登录用户使用Cookie存储
- 已登录用户数据持久化到数据库
- 支持商品有效期(30天自动清除)
购物车逻辑:
python复制class Cart:
def __init__(self, request):
self.session = request.session
cart = self.session.get('cart', {})
self.cart = cart
def add(self, product, quantity=1):
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {
'quantity': 0,
'price': str(product.price)
}
self.cart[product_id]['quantity'] += quantity
self.save()
def save(self):
self.session['cart'] = self.cart
self.session.modified = True
4.2 订单流程
订单状态机设计:
python复制ORDER_STATUS = (
('pending', '待支付'),
('paid', '已支付'),
('shipped', '已发货'),
('completed', '已完成'),
('cancelled', '已取消'),
('refunded', '已退款')
)
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=20, choices=ORDER_STATUS, default='pending')
total = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
def can_cancel(self):
return self.status in ['pending', 'paid']
def process_payment(self):
if self.status != 'pending':
raise ValueError("订单状态异常")
# 支付逻辑...
self.status = 'paid'
self.save()
5. 性能优化实践
5.1 数据库优化
-
索引策略:
- 为所有外键添加索引
- 高频查询字段(如商品名称、价格)添加复合索引
- 使用django-debug-toolbar分析慢查询
-
查询优化:
- 避免在循环中查询数据库
- 使用select_related/prefetch_related
- 对大表使用分页查询
5.2 前端性能优化
- 图片懒加载:
html复制<img data-src="product.jpg" class="lazyload" alt="Product">
<script>
document.addEventListener("DOMContentLoaded", function() {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazyload"));
if ("IntersectionObserver" in window) {
let lazyImageObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
}
});
</script>
- Webpack配置优化:
javascript复制module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
6. 部署与运维
6.1 生产环境部署
系统采用Docker容器化部署,主要组件包括:
- Nginx:作为反向代理和静态文件服务器
- Gunicorn:应用服务器
- PostgreSQL:生产环境数据库
- Redis:缓存和消息队列
docker-compose.yml示例:
yaml复制version: '3'
services:
web:
build: .
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- redis
- db
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: mysecretpassword
volumes:
- postgres_data:/var/lib/postgresql/data/
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- redis_data:/data
nginx:
image: nginx:1.19
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./static:/static
depends_on:
- web
volumes:
postgres_data:
redis_data:
6.2 监控与日志
- 使用Sentry捕获异常:
python复制import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="your-dsn-here",
integrations=[DjangoIntegration()],
traces_sample_rate=1.0,
send_default_pii=True
)
- 日志配置:
python复制LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/django/debug.log',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
7. 安全防护措施
7.1 常见攻击防护
- CSRF防护:
python复制MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
# ...
]
# 模板中使用
<form method="post">{% csrf_token %}
- XSS防护:
- 所有用户输入使用Django模板自动转义
- 富文本内容使用django-bleach过滤
- SQL注入防护:
- 坚持使用Django ORM
- 必须使用原生SQL时,使用参数化查询
7.2 数据安全
- 敏感数据加密:
python复制from django.db import models
from django_cryptography.fields import encrypt
class UserProfile(models.Model):
credit_card = encrypt(models.CharField(max_length=255))
- 定期备份策略:
bash复制# 数据库备份
pg_dump -U username dbname > backup.sql
# 媒体文件备份
rsync -avz /path/to/media user@backup-server:/backup/media
8. 项目经验与教训
在开发这个系统的过程中,我积累了几个关键经验:
-
性能优化要尽早:在开发中期才发现商品列表页加载缓慢,重构花费了大量时间。建议在项目初期就建立性能基准。
-
测试覆盖率很重要:最初忽视单元测试,导致后期修改频繁引入回归问题。建议保持至少80%的测试覆盖率。
-
文档同步更新:API文档与代码不同步给团队协作带来困扰。现在使用Swagger实现文档自动化。
-
监控不可或缺:生产环境没有完善的监控,导致问题发现滞后。现在使用Prometheus+Grafana构建完整监控体系。
对于想要开发类似系统的开发者,我的建议是:
- 先从核心功能MVP开始,不要过度设计
- 重视自动化部署和CI/CD流程
- 做好容量规划,特别是数据库设计
- 建立完善的日志和监控系统