You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:17:34