Django+微信小程序构建农产品电商平台实战
1. 项目概述:Django+Python微信小程序农产品交易平台
去年帮老家县城的农产品合作社搭建线上销售平台时,我选择了Django+微信小程序的技术方案。这个组合在县域农产品电商场景中表现出色——后台用Django处理复杂的交易逻辑,前端用微信小程序触达乡镇用户。三个月内平台交易额突破200万,验证了技术选型的合理性。
农产品交易平台的核心是解决供需匹配问题。农户需要展示商品、管理库存、接收订单;采购商需要比价、下单、跟踪物流;平台方需要管理交易、结算、数据统计。Django的MTV架构完美适配这种多角色系统,而微信小程序则提供了零安装成本的移动端入口。
2. 技术架构设计
2.1 整体技术栈选型
后端采用经典的Django三层架构:
- 模型层:使用Django ORM定义农产品、订单、用户等核心模型
- 模板层:DRF(Django REST Framework)提供API接口
- 视图层:基于类的视图处理业务逻辑
前端采用微信小程序+Web双端策略:
- 微信小程序:主攻移动端用户,利用微信支付能力
- 管理后台:Vue+ElementUI供运营人员使用
数据库选用MySQL 8.0,关键配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'agri_mall',
'CONN_MAX_AGE': 300, # 连接池优化
'OPTIONS': {
'charset': 'utf8mb4', # 支持emoji存储
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"
}
}
}
2.2 高并发解决方案
针对农产品抢购场景,我们采用多级缓存策略:
- 商品详情页:Redis缓存+本地缓存
- 库存管理:Redis原子操作+异步扣减
# 库存扣减示例
def reduce_stock(product_id, count):
with transaction.atomic():
product = Product.objects.select_for_update().get(id=product_id)
if product.stock >= count:
product.stock -= count
product.save()
return True
return False
3. 核心功能实现
3.1 微信小程序登录集成
小程序端通过wx.login获取code,后端用code换取openid:
# settings.py
WX_APPID = 'your_appid'
WX_SECRET = 'your_secret'
# views.py
def wx_login(request):
code = request.POST.get('code')
url = f"https://api.weixin.qq.com/sns/jscode2session?appid={WX_APPID}&secret={WX_SECRET}&js_code={code}&grant_type=authorization_code"
response = requests.get(url)
data = response.json()
openid = data.get('openid')
# ...后续用户创建/登录逻辑
重要提示:切勿在前端存储session_key,应通过HTTPS传输并仅在服务端保存
3.2 农产品交易流程实现
订单状态机设计(简化版):
class Order(models.Model):
STATUS_CHOICES = (
('unpaid', '待支付'),
('paid', '已支付'),
('shipped', '已发货'),
('completed', '已完成'),
('cancelled', '已取消')
)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='unpaid')
def can_pay(self):
return self.status == 'unpaid'
def pay(self):
if self.can_pay():
self.status = 'paid'
self.save()
支付回调处理要点:
- 验证微信支付签名
- 处理重复通知
- 记录支付日志
@csrf_exempt
def wxpay_callback(request):
xml_data = request.body.decode('utf-8')
result = parse_xml(xml_data)
if verify_signature(result):
out_trade_no = result['out_trade_no']
with transaction.atomic():
order = Order.objects.select_for_update().get(order_no=out_trade_no)
if not order.is_paid: # 防止重复处理
order.pay()
PaymentLog.objects.create(
order=order,
amount=result['total_fee'],
transaction_id=result['transaction_id']
)
return HttpResponse(gen_xml({'return_code': 'SUCCESS'}))
4. 性能优化实践
4.1 数据库查询优化
农产品列表页的N+1问题解决方案:
# 错误写法(产生N+1查询)
products = Product.objects.all()
for p in products:
print(p.category.name) # 每次循环都查询数据库
# 优化写法
products = Product.objects.select_related('category').all()
复杂查询使用annotate和prefetch_related:
from django.db.models import Count, Avg
# 获取各类农产品平均价格
categories = Category.objects.annotate(
avg_price=Avg('products__price'),
product_count=Count('products')
).filter(product_count__gt=0)
4.2 微信小程序端优化
图片加载优化方案:
- 使用CDN加速静态资源
- 实现懒加载
- 压缩图片到合适尺寸
<!-- wxml示例 -->
<image lazy-load mode="widthFix" src="{{item.thumb_url}}"></image>
数据分页加载实现:
// 小程序端
Page({
data: {
page: 1,
loading: false,
hasMore: true
},
loadMore() {
if (this.data.loading || !this.data.hasMore) return
this.setData({ loading: true })
wx.request({
url: '/api/products/',
data: { page: this.data.page },
success: (res) => {
if (res.data.length < 10) {
this.setData({ hasMore: false })
}
this.setData({
list: [...this.data.list, ...res.data],
page: this.data.page + 1
})
},
complete: () => this.setData({ loading: false })
})
}
})
5. 部署与运维实战
5.1 服务器部署方案
推荐使用Docker Compose部署:
version: '3'
services:
web:
build: .
command: gunicorn agri_mall.wsgi:application --bind 0.0.0.0:8000 --workers 4
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- redis
- db
redis:
image: redis:6-alpine
ports:
- "6379:6379"
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: yourpassword
MYSQL_DATABASE: agri_mall
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
关键配置参数:
- Gunicorn workers数量 = CPU核心数 * 2 + 1
- MySQL连接池大小 ≈ (最大并发请求数 / 平均请求耗时) * 1.2
5.2 监控与日志
使用Sentry捕获异常:
# settings.py
INSTALLED_APPS += ('sentry_sdk',)
import sentry_sdk
sentry_sdk.init(
dsn="your_dsn",
integrations=[DjangoIntegration()],
traces_sample_rate=1.0,
send_default_pii=True
)
日志分割配置(使用logrotate):
/var/log/agri_mall/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
kill -HUP `cat /var/run/gunicorn.pid`
endscript
}
6. 踩坑经验与解决方案
6.1 微信支付证书问题
典型错误: SSL_do_handshake() failed 解决方法:
- 确保证书文件路径正确
- 使用requests的证书配置方式:
import requests
resp = requests.post(url, data=data, cert=(
'/path/to/apiclient_cert.pem',
'/path/to/apiclient_key.pem'
))
6.2 Django时区问题
现象:数据库时间与显示时间不一致 解决方案:
# settings.py
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True # 启用时区支持
# 模板中显示时间
{{ value|date:"Y-m-d H:i:s" }}
{{ value|timezone:"Asia/Shanghai"|date:"Y-m-d H:i:s" }}
6.3 小程序图片上传限制
突破微信小程序单次上传图片数量限制的方案:
- 分批上传
- 使用web-view组件调用H5上传接口
- 后台合并图片
实现示例:
// 小程序端
const uploadFiles = (files) => {
const batchSize = 5
for (let i = 0; i < files.length; i += batchSize) {
const batch = files.slice(i, i + batchSize)
wx.uploadFile({
url: 'https://yourdomain.com/api/upload/',
filePath: batch[0],
name: 'file',
formData: {
'index': i,
'total': files.length
},
success: (res) => {
console.log(`Batch ${i/batchSize + 1} uploaded`)
}
})
}
}
7. 扩展功能建议
7.1 农产品溯源系统
基于区块链的简单实现方案:
- 使用Hyperledger Fabric搭建私有链
- 定义农产品溯源智能合约
- Django通过gRPC与区块链网络交互
核心模型设计:
class ProductTrace(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
block_hash = models.CharField(max_length=64) # 区块链交易哈希
timestamp = models.DateTimeField(auto_now_add=True)
operation = models.CharField(max_length=20) # 种植/施肥/收割等
operator = models.ForeignKey(User, on_delete=models.PROTECT)
details = models.JSONField()
7.2 智能推荐系统
基于用户行为的简单推荐算法:
from collections import defaultdict
def recommend_products(user):
# 获取同类用户购买记录
similar_users = get_similar_users(user)
product_scores = defaultdict(int)
for u in similar_users:
for p in u.purchased_products.all():
product_scores[p] += 1
# 排除已购买商品
purchased_ids = user.purchased_products.values_list('id', flat=True)
return sorted(
[p for p in product_scores.items() if p[0].id not in purchased_ids],
key=lambda x: -x[1]
)[:10]
小程序端展示优化:在商品详情页添加"相似推荐"模块,提升转化率15%-20%。
8. 项目演进方向
技术架构的迭代路径:
- 初期:Django单体架构(快速验证)
- 成长期:
- 引入Celery处理异步任务
- 用Redis实现缓存和消息队列
- 成熟期:
- 服务拆分(用户服务、商品服务、订单服务)
- 引入Kubernetes管理容器
性能指标监控体系:
- 接口响应时间(P99 < 500ms)
- 数据库查询耗时(< 100ms)
- 小程序页面加载时间(首屏 < 1s)
- 支付成功率(> 98%)
这套架构在日订单量5万级别仍能保持稳定,通过合理的缓存策略和数据库优化,服务器成本可控制在每月2000元以内(基于阿里云4核8G配置)。
更多推荐




所有评论(0)