1. 项目概述:基于Django的洗衣服务电商平台
这个项目是一个典型的O2O(线上到线下)洗衣服务平台,采用Django作为后端框架构建。作为从业十多年的全栈开发者,我认为这类项目最核心的价值在于打通传统洗衣行业的数字化闭环——用户通过Web端/移动端下单,商家通过管理系统接单,物流完成衣物取送,最终形成完整的服务链条。
从技术架构来看,项目包含三个关键子系统:面向消费者的前端展示与订单系统(可能采用Django模板或前后端分离架构)、面向商家的运营管理系统、以及连接线下洗衣工厂的ERP接口。这种架构设计既保证了C端用户体验的流畅性,又满足了B端复杂业务管理的需求。
2. 技术选型与核心组件
2.1 为什么选择Django?
在评估了Flask、FastAPI等框架后,我们最终选择Django主要基于以下考量:
- 内置Admin系统:洗衣平台需要强大的后台管理功能,Django Admin开箱即用的特性可节省60%以上的后台开发时间
- ORM优势:对于涉及多状态转换的订单系统(待接单→洗涤中→配送中→已完成),Django ORM的状态机实现比原生SQL更易维护
- 安全机制:自动防范CSRF、XSS等攻击,对于涉及在线支付的平台至关重要
实际开发中发现:Django 3.2版本对PostgreSQL的JSONField支持大幅优化,这对存储衣物特殊处理要求(如"羊毛衫需冷水手洗"等非结构化数据)非常有利
2.2 核心模型设计
洗衣平台的核心数据模型包括:
class Order(models.Model): STATUS_CHOICES = [ ('pending', '待接单'), ('accepted', '已接单'), ('washing', '洗涤中'), ('delivering', '配送中'), ('completed', '已完成'), ('cancelled', '已取消') ] user = models.ForeignKey(User, on_delete=models.CASCADE) pickup_address = models.TextField() delivery_address = models.TextField() total_price = models.DecimalField(max_digits=8, decimal_places=2) status = models.CharField(max_length=20, choices=STATUS_CHOICES) special_instructions = models.JSONField(default=dict) # 存储特殊洗涤要求 class Garment(models.Model): WASH_TYPES = [ ('normal', '普通水洗'), ('dry', '干洗'), ('hand', '手洗') ] order = models.ForeignKey(Order, related_name='garments', on_delete=models.CASCADE) garment_type = models.CharField(max_length=50) wash_type = models.CharField(max_length=20, choices=WASH_TYPES) price = models.DecimalField(max_digits=6, decimal_places=2)3. 关键业务逻辑实现
3.1 订单状态机设计
洗衣订单的生命周期管理是系统核心,我们采用Django FSM(有限状态机)实现:
from django_fsm import FSMField, transition class Order(models.Model): state = FSMField(default='pending') @transition(field=state, source='pending', target='accepted') def accept(self): """商家接单""" self.accepted_at = timezone.now() @transition(field=state, source='accepted', target='washing') def start_washing(self): """开始洗涤""" require_staff_permission('can_wash') @transition(field=state, source='washing', target='delivering') def finish_washing(self): """完成洗涤""" self.washing_completed_at = timezone.now()3.2 价格计算策略
洗衣服务的定价需要考虑衣物类型、洗涤方式和附加服务(如加急):
def calculate_price(garments, is_urgent=False): base_price = sum(g.price for g in garments) if is_urgent: base_price *= 1.3 # 加急费30% # 冬季大衣干洗额外费用 heavy_winter_coat = any( g.garment_type == 'winter_coat' and g.wash_type == 'dry' for g in garments ) if heavy_winter_coat: base_price += 15 return base_price4. 性能优化实践
4.1 查询优化
订单列表页的N+1查询问题是常见性能瓶颈:
# 错误做法:导致N+1查询 orders = Order.objects.all() for order in orders: print(order.user.username) # 每次循环都查询数据库 # 正确做法:使用select_related orders = Order.objects.select_related('user').all()对于衣物列表这种一对多关系,使用prefetch_related更高效:
orders = Order.objects.prefetch_related('garments').filter( status='completed' )4.2 缓存策略
采用Redis缓存两类高频访问数据:
- 服务价格表(每6小时更新)
- 用户最近订单(个人中心展示)
from django.core.cache import cache def get_service_prices(): prices = cache.get('service_prices') if not prices: prices = GarmentPrice.objects.all().values_list('garment_type', 'price') cache.set('service_prices', prices, 60*60*6) # 6小时过期 return prices5. 部署方案
5.1 宝塔面板部署要点
在宝塔环境部署Django项目时需特别注意:
- 静态文件配置:
location /static/ { alias /www/wwwroot/laundry/static/; expires 30d; }- 媒体文件权限:
chown -R www:www /www/wwwroot/laundry/media chmod -R 755 /www/wwwroot/laundry/media- Gunicorn配置:
[program:laundry_gunicorn] command=/www/wwwroot/laundry/venv/bin/gunicorn laundry.wsgi:application -c /www/wwwroot/laundry/gunicorn.conf.py directory=/www/wwwroot/laundry user=www autostart=true autorestart=true5.2 安全加固措施
- 生产环境必须设置:
SECURE_HSTS_SECONDS = 31536000 # 1年HSTS SECURE_CONTENT_TYPE_NOSNIFF = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True- 敏感配置使用环境变量:
# settings.py import os SECRET_KEY = os.environ['DJANGO_SECRET_KEY']6. 典型问题排查
6.1 时区问题
洗衣订单的时间记录必须正确处理时区:
# settings.py TIME_ZONE = 'Asia/Shanghai' USE_TZ = True # 创建订单时 from django.utils import timezone order.created_at = timezone.now()6.2 文件上传限制
处理用户上传的衣物照片时,需在Nginx和Django两端配置:
# nginx.conf client_max_body_size 20M;# settings.py DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 20 # 20MB7. 扩展功能建议
7.1 微信小程序集成
通过Django REST framework提供API:
from rest_framework.viewsets import ModelViewSet class OrderViewSet(ModelViewSet): queryset = Order.objects.all() serializer_class = OrderSerializer def get_queryset(self): return super().get_queryset().filter(user=self.request.user)7.2 智能调度算法
基于地理位置的取件路线优化:
from geopy.distance import great_circle def optimize_pickup_route(orders): """使用贪心算法优化取件路线""" if not orders: return [] current_location = (31.2304, 121.4737) # 洗衣店坐标 route = [] while orders: nearest = min( orders, key=lambda o: great_circle( current_location, (o.pickup_lat, o.pickup_lng) ).km ) route.append(nearest) current_location = (nearest.pickup_lat, nearest.pickup_lng) orders.remove(nearest) return route8. 监控与日志
8.1 异常监控
使用Sentry捕获生产环境异常:
# settings.py INSTALLED_APPS += ('sentry_sdk',) import sentry_sdk sentry_sdk.init( dsn="https://example@sentry.io/1", integrations=[DjangoIntegration()] )8.2 业务日志
关键操作记录审计日志:
import logging audit_log = logging.getLogger('audit') def accept_order(order, staff): order.accept() audit_log.info( f"Order {order.id} accepted by {staff.username}", extra={ 'order_id': order.id, 'staff_id': staff.id, 'action': 'accept' } )这个项目让我深刻体会到Django在快速构建复杂业务系统时的优势。特别是在处理状态复杂的订单流程时,Django Admin配合django-fsm的组合极大提升了开发效率。实际运营中,我们后来增加了衣物RFID追踪功能,通过Django Channels实现了实时状态推送,这部分扩展也充分证明了Django生态的灵活性