在Django项目中实现已取消订单的折扣码复用功能
实现订单取消后折扣码可复用的Django方案
要解决订单取消后折扣码可复用且保留数据追踪的需求,核心思路是给UsedCode模型增加状态标记,区分有效使用和已取消的记录,统计使用次数时仅计算有效记录即可。具体步骤如下:
1. 修改UsedCode模型,添加状态字段
给UsedCode新增一个状态字段,用来标记该折扣码使用记录是否有效。同时调整原有使用次数统计方法,只统计有效状态的记录:
from django.db import models from django.core.validators import MaxValueValidator class CouponCode(models.Model): max_usage = models.PositiveSmallIntegerField() max_usage_per_user = models.PositiveSmallIntegerField(default=1) code = models.CharField(max_length=10, unique=True) discount_percent = models.PositiveSmallIntegerField(default=0, validators=[MaxValueValidator(100)]) max_discount_amount = models.PositiveIntegerField(default=0) is_active = models.BooleanField(default=True) start_date = models.DateTimeField(null=True, blank=True) end_date = models.DateTimeField(null=True, blank=True) minimum_price = models.PositiveBigIntegerField(default=0) class UsedCode(models.Model): customer = models.PositiveBigIntegerField(verbose_name='customer id') coupon = models.ForeignKey(CouponCode, on_delete=models.PROTECT) order_id = models.PositiveIntegerField() # 新增状态字段,标记记录是否有效 STATUS_CHOICES = ( ('active', '已使用'), ('cancelled', '已取消'), ) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='active') @classmethod def has_reached_max_usage_for_user(cls, coupon, user): # 仅统计状态为active的有效记录 active_usages = cls.objects.filter(coupon=coupon, customer=user, status='active').count() return active_usages >= coupon.max_usage_per_user @classmethod def has_reached_max_usage(cls, coupon): # 仅统计状态为active的有效记录 active_usages = cls.objects.filter(coupon=coupon, status='active').count() return active_usages >= coupon.max_usage
注:修正了原代码中CharField漏写models.、validators括号错误的问题,确保模型能正常运行。
2. 订单取消时更新UsedCode状态
当订单取消时,找到对应订单的UsedCode记录,将其状态更新为cancelled。可以在订单取消的业务逻辑中添加这段代码:
# 示例:在订单取消函数中更新状态 def handle_order_cancellation(order): # 处理订单取消的其他逻辑(比如库存回滚、通知用户等) # 更新对应折扣码使用记录的状态 UsedCode.objects.filter(order_id=order.id).update(status='cancelled')
如果你的订单模型用信号触发取消逻辑,可将这段更新代码放到对应的信号处理器中。
3. 可选优化:增加时间追踪字段
如果需要更细致的审计,可以给UsedCode添加updated_at字段,记录状态更新时间:
class UsedCode(models.Model): # 原有字段... updated_at = models.DateTimeField(auto_now=True)
这样能清晰看到每条记录的状态变更时间,方便后续排查和数据分析。
这种方案的优势:
- 完整保留所有折扣码使用记录,包括已取消的,满足数据追踪需求
- 统计使用次数时仅计算有效记录,订单取消后用户可再次使用折扣码(只要未达到使用次数上限)
- 无需删除数据,避免数据丢失风险
内容的提问来源于stack exchange,提问作者Mohammad Goodarzi
相关产品推荐
相关产品推荐

