1. 项目背景与核心价值
超市销售系统是零售行业最基础也最核心的管理工具。传统的手工记账或单机版管理系统已经无法满足现代超市的运营需求——实时库存更新、多终端协同、销售数据分析等功能成为刚需。这正是我们选择Python+Django技术栈开发这套系统的原因。
Django作为Python生态中最成熟的全栈Web框架,其"开箱即用"的特性特别适合快速构建功能完备的管理系统。我在实际开发中发现,相比PHP的Laravel或Java的Spring Boot,Django在以下场景具有独特优势:
- 自带Admin后台,半小时就能搭建出可操作的数据管理界面
- ORM设计优雅,用Python类就能定义数据模型,无需手写SQL
- 完善的Auth权限系统,轻松实现不同角色的访问控制
这个项目完整实现了超市日常运营的六大核心模块:
- 商品管理(分类、条码、定价)
- 库存管理(入库、盘点、预警)
- 收银终端(小票打印、支付对接)
- 会员系统(积分、折扣)
- 销售分析(热销商品、时段统计)
- 员工权限(角色分配、操作日志)
提示:系统采用前后端不分离架构,模板渲染使用Django原生模板引擎,适合中小型超市部署。如需应对高并发场景,可参考本文最后的扩展方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境搭建与依赖安装
2.1 Python环境配置
推荐使用Python 3.8+版本,这是目前Django 4.x最稳定的运行环境。避免使用Python 3.10+可能遇到的兼容性问题。以下是经实测可靠的安装步骤:
bash复制# Ubuntu/Linux
sudo apt update
sudo apt install python3.8 python3.8-venv
# Windows
# 从python.org下载3.8.x安装包
# 务必勾选"Add Python to PATH"
创建隔离的虚拟环境(这是避免依赖冲突的关键步骤):
bash复制python -m venv .venv
source .venv/bin/activate # Linux/Mac
.venv\Scripts\activate # Windows
2.2 Django与依赖库安装
项目依赖清单(requirements.txt)应包含以下核心组件:
code复制Django==4.0.6
django-crispy-forms==1.14.0 # 美化表单
Pillow==9.2.0 # 图片处理
django-tables2==2.6.0 # 数据表格
reportlab==3.6.12 # PDF小票生成
安装命令:
bash复制pip install -r requirements.txt
注意:如果遇到mysqlclient安装失败,可先安装系统依赖:
bash复制sudo apt install libmysqlclient-dev # Ubuntu brew install mysql-client # Mac
3. 数据库设计与模型实现
3.1 核心数据模型
Django的ORM让我们可以用Python类定义数据库结构。以下是经过三个超市项目验证的模型设计:
python复制from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
class Product(models.Model):
barcode = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
selling_price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
alert_threshold = models.PositiveIntegerField(default=10) # 库存预警值
class Sale(models.Model):
TRANSACTION_TYPES = [
('CASH', '现金'),
('CARD', '银行卡'),
('MOBILE', '移动支付')
]
cashier = models.ForeignKey(User, on_delete=models.PROTECT)
transaction_type = models.CharField(max_length=10, choices=TRANSACTION_TYPES)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
3.2 数据库迁移与优化
生成迁移文件并应用:
bash复制python manage.py makemigrations
python manage.py migrate
针对查询性能的优化建议:
- 为高频查询字段添加索引:
python复制class Meta: indexes = [ models.Index(fields=['barcode']), models.Index(fields=['name']) ] - 使用select_related减少查询次数:
python复制Product.objects.select_related('category').filter(stock__lt=F('alert_threshold')) - 对大表考虑分库分表策略
4. 核心功能实现细节
4.1 收银终端实现
收银界面需要处理高并发写入,关键实现点:
python复制# views.py
from django.views.decorators.csrf import csrf_exempt
from django.db import transaction
@csrf_exempt
@transaction.atomic
def checkout(request):
cart_items = json.loads(request.POST.get('items'))
# 创建销售主记录
sale = Sale.objects.create(
cashier=request.user,
transaction_type=request.POST.get('payment_type'),
total_amount=calculate_total(cart_items)
)
# 处理每个商品
for item in cart_items:
product = Product.objects.select_for_update().get(pk=item['id'])
if product.stock < item['qty']:
raise ValueError(f"{product.name}库存不足")
product.stock -= item['qty']
product.save()
SaleDetail.objects.create(
sale=sale,
product=product,
quantity=item['qty'],
unit_price=product.selling_price
)
generate_receipt(sale) # 生成小票
return JsonResponse({'status': 'success'})
关键点:使用select_for_update()实现行级锁,避免超卖;整个操作包裹在事务中保证原子性。
4.2 库存预警功能
通过Django Signals实现低库存自动提醒:
python复制# signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Product)
def check_stock(sender, instance, **kwargs):
if instance.stock < instance.alert_threshold:
alert = StockAlert(
product=instance,
current_stock=instance.stock
)
alert.save()
send_alert_email(alert) # 自定义邮件发送
5. 部署方案与性能优化
5.1 生产环境部署
推荐使用Nginx + Gunicorn组合:
bash复制# 安装Gunicorn
pip install gunicorn
# 启动命令
gunicorn --workers 4 --bind unix:/tmp/gunicorn.sock supermarket.wsgi:application
Nginx配置示例:
nginx复制server {
listen 80;
server_name yourdomain.com;
location /static/ {
alias /path/to/static/files;
}
location / {
proxy_pass http://unix:/tmp/gunicorn.sock;
proxy_set_header Host $host;
}
}
5.2 性能优化技巧
-
缓存策略:
python复制# settings.py CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/1', } } # views.py from django.views.decorators.cache import cache_page @cache_page(60 * 15) # 缓存15分钟 def product_list(request): ... -
静态文件处理:
bash复制
python manage.py collectstatic -
数据库连接池:
python复制# settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '5432', 'CONN_MAX_AGE': 300, # 连接池保持时间 } }
6. 项目扩展与二次开发
6.1 移动端API支持
如需对接小程序或APP,可增加DRF(Django REST Framework):
python复制# serializers.py
from rest_framework import serializers
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['id', 'barcode', 'name', 'selling_price']
# views.py
from rest_framework import generics
class ProductListAPI(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
6.2 数据分析增强
集成Pandas进行销售分析:
python复制def sales_report(start_date, end_date):
queryset = Sale.objects.filter(
created_at__range=(start_date, end_date)
).values('created_at__date', 'product__name').annotate(
total=Sum('total_amount'),
count=Count('id')
)
df = pd.DataFrame.from_records(queryset)
pivot = df.pivot_table(
index='created_at__date',
columns='product__name',
values='total',
aggfunc='sum'
)
return pivot.plot(kind='bar', stacked=True)
7. 常见问题排查
7.1 静态文件404错误
检查项:
- DEBUG=False时必须设置STATIC_ROOT
- Nginx配置的alias路径是否正确
- 确保执行了collectstatic
7.2 数据库连接超时
解决方案:
python复制# settings.py
DATABASES = {
'default': {
...
'OPTIONS': {
'connect_timeout': 5,
}
}
}
7.3 时区问题
最佳实践:
python复制# settings.py
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True # 启用时区支持
8. 项目源码结构说明
完整项目包含以下关键目录:
code复制/supermarket
/apps
/products # 商品管理
/sales # 销售模块
/reports # 报表系统
/static
/css # Bootstrap定制样式
/js # 收银台交互脚本
/templates
/admin # 后台模板覆盖
/pos # 收银界面
manage.py
requirements.txt
README.md # 完整部署指南
我在实际部署中发现三个易忽略点:
- MEDIA_ROOT需要额外Nginx配置才能访问上传文件
- 生产环境必须设置ALLOWED_HOSTS
- 定期备份数据库应写入crontab
