姜戈。如何减少每次使用后的优惠券总数

Dan*_*nny 8 django django-templates django-models django-forms

我正在学习开发一个电子商务网站,我有一个带有 used 和 max_value 的优惠券模型,它负责处理可用优惠券的最大数量,我想在我的观点中实现这一点,这样如果优惠券被兑换的次数超过max_value(优惠券数量),那么它应该显示一条错误消息。我以有限的知识尝试过的任何事情都会导致错误。

如何增加视图中的“已使用”?

这是更容易理解的方式:

用户(卖家)可以创建优惠券。代码是字母数字(它应该是唯一的 - 我需要尝试解决这个问题)。任何人只能使用一次优惠券。max_value 由创建它的用户设置,每次有人使用优惠券时,'used' 应该自动附加。假设有 10 张优惠券,每次客户使用一张优惠券时,'used' 应该增加 1,直到达到 max_value。如果达到max_value,则优惠券无效。这就是我正在努力实现的目标。

意见

class AddCouponView(View, LoginRequiredMixin):
def post(self, *args, **kwargs):
    now = timezone.now()
    form = CouponForm(self.request.POST or None)
    if form.is_valid():
        try:
            code = form.cleaned_data.get('code')
            order = Order.objects.get(user=self.request.user, complete=False)
            coupon_qs = Coupon.objects.filter(code__iexact=code, valid_from__lte=now,
                                            valid_to__gte=now)
            order_coupon = Order.objects.filter(coupon=coupon_qs.first(), user=self.request.user)

            if order_coupon:
                messages.error(self.request, 'You can\'t use same coupon again')
                return redirect('store:checkout')
            if coupon_qs:
                    order.coupon = coupon_qs[0]
                    order.save()
                    messages.success(self.request, "Successfully added coupon")
                    return redirect('store:checkout')
            else:
                messages.success(self.request, "Coupon Does not Exists")
                return redirect('store:checkout')

        except ObjectDoesNotExist:
            messages.info(self.request, "You do not have an active order")
            return redirect('store:checkout')
Run Code Online (Sandbox Code Playgroud)

模型

class Coupon(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
code = models.CharField(max_length=15)
amount = models.FloatField()
valid_from = models.DateTimeField(null=True)
valid_to = models.DateTimeField(null=True)
max_value = models.IntegerField(validators=[MaxValueValidator(100)], verbose_name='Coupon Quantity', null=True) # No. of coupon
used = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)

谢谢

rud*_*dra 3

如果我理解正确的话,也许你可以尝试这样:

from django.db.models import F

...
if form.is_valid():
    code = form.cleaned_data.get('code')
    order = Order.objects.get(user=self.request.user, complete=False)
    coupon = Coupon.objects.filter(code__iexact=code, valid_from__lte=now, valid_to__gte=now).exclude(order__user=self.request.user,max_value__lte=F('used')).first()
    if not coupon:
        messages.error(self.request, 'You can\'t use same coupon again, or coupon does not exist')
        return redirect('store:checkout')
    else:
        try:
            coupon.used += 1
            coupon.save()
            order.coupon = coupon
            order.save()
            messages.success(self.request, "Successfully added coupon")
        except:
            messages.error(self.request, "Max level exceeded for coupon")
        
        return redirect('store:checkout')
Run Code Online (Sandbox Code Playgroud)

说明:我正在查询优惠券是否有效并且有确切的代码。我使用订单和优惠券之间的反向关系排除用户已经使用的任何优惠券。如果模型中定义了任何相关名称Order,则反向查询将为exclude(<related_name>__user=self.request.user)。我还排除了任何价值等于的优惠used券max_value。然后我获取查询集的第一个值并在Order对象中使用它。used最后,我为的属性添加+1 Coupon。

更新:在模型中添加约束

您可以在模型中添加一个constraint,使其不超过max_value:

from django.db.models import Q, F

class Coupon(models.Model):
    ...
    class Meta:
        constraints = [
            models.CheckConstraint(check=Q(used__lte=F('max_value')), name="constrain-max-limit")
        ]
Run Code Online (Sandbox Code Playgroud)