Django的。每次使用后如何减少优惠券总数 [英] Django. How to reduce total number of coupons after each use

查看:94
本文介绍了Django的。每次使用后如何减少优惠券总数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在学习开发一个电子商务网站,我有一个使用过的优惠券模型和max_value,用于处理可使用的优惠券的最大数量,我想在我的观点中实现,例如,如果优惠券兑现的金额超过了max_value(优惠券数量),那么它应该显示错误消息。

Hey guys I am learning to develop a ecommerce website, I have a coupon model with used and max_value, which take care of max number of coupon available to use, I want to implement that in my views, such that if the coupon is redeemed more than the max_value(number of coupons), then it should show an error message. Whatever I have tried with my limited knowledge is resulting in errors.

如何增加视图中的已用?

How can I increment the 'used' in views?

这是更容易理解的方式:

This is in much more understandable way:

用户(卖方)能够创建优惠券。代码是字母数字(应该是唯一的-我需要尝试解决)。优惠券只能由任何人使用一次。 max_value由创建它的用户设置,每当有人使用优惠券时,使用过的都会自动附加。假设有10张优惠券,那么每当客户使用一张优惠券时,已使用应加1,直到达到max_value。如果达到max_value,则优惠券应该无效。这就是我要实现的目标。

users(sellers) are able to create coupons. code is the alpha numeric (which should be unique - i need to try work that out). The coupon can be used by anyone only once. max_value is set by the user who creates it, and each time someone uses coupons, the 'used' should get automatically appended. suppose there are 10 coupons, every time a customer uses one coupon, the 'used' should get incremented by 1 till it reaches max_value. if it reaches max_value, coupon should be invalid. This is what I am trying to achieve.

views

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')

模型

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)

谢谢

推荐答案

如果我理解正确,也许您可​​以这样尝试:

If I understood correctly, maybe you can try like this:

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')

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

Explanation: I am querying if a coupon is valid and has exact code. I am excluding any coupon which are already used by the user using reverse relationship between Order and Coupon. If you have any related name defined in the Order model, then the reverse query will be exclude(<related_name>__user=self.request.user). I am also excluding any coupon which has value of used equals to max_value. Then I am taking the queryset's first value and using it in the Order object. Finally, I am adding +1 to the used attribute of Coupon.

您可以添加模型中的约束 ,以使其不超过 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")
        ]

这篇关于Django的。每次使用后如何减少优惠券总数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆