【问题标题】:How to calculate the points based on the price of the total purchase in django models?如何根据 django 模型中的总购买价格计算积分?
【发布时间】:2021-07-19 13:10:05
【问题描述】:

我正在尝试创建用户在购买东西并从前端下订单后赚取的积分。另外,我需要将积分保存在数据库中,因为用户以后会使用这些积分购买东西。

积分系统如下所示。

Point System for % of the total purchase
Upto 10,000 = 1 %
10k to 50k =2.75%
50K plus = 5%

我没有将价格保存在数据库中,我只是将其用作财产,这样它就可以保持安全并且任何人都无法更改。它会在调用 get 或 post API 时进行计算。

 class Order(models.Model):
        ORDER_STATUS = (
            ('To_Ship', 'To Ship',),
            ('Shipped', 'Shipped',),
            ('Delivered', 'Delivered',),
            ('Cancelled', 'Cancelled',),
        )
        user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)    
        order_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')
        ordered_date = models.DateTimeField(auto_now_add=True)
        ordered = models.BooleanField(default=False)  



    @property
    def total_price(self):
        # abc = sum([_.price for _ in self.order_items.all()])
        # print(abc)
        return sum([_.price for _ in self.order_items.all()])

    def __str__(self):
        return self.user.email

    class Meta:
        verbose_name_plural = "Orders"
        ordering = ('-id',)

class OrderItem(models.Model):   
    orderItem_ID = models.CharField(max_length=12, editable=False, default=id_generator)
    order = models.ForeignKey(Order,on_delete=models.CASCADE, blank=True,null=True,related_name='order_items')
    item = models.ForeignKey(Product, on_delete=models.CASCADE,blank=True, null=True)
    order_variants = models.ForeignKey(Variants, on_delete=models.CASCADE,blank=True,null=True)
    quantity = models.IntegerField(default=1)


ORDER_STATUS = (
    ('To_Ship', 'To Ship',),
    ('Shipped', 'Shipped',),
    ('Delivered', 'Delivered',),
    ('Cancelled', 'Cancelled',),
)
order_item_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')

@property
def price(self):
    total_item_price = self.quantity * self.order_variants.price
    return total_item_price

更新代码:

class Points(models.Model):
    order = models.OneToOneField(Order,on_delete=models.CASCADE,blank=True,null=True)
    points_gained = models.IntegerField(default=0)

    def collect_points(sender,instance,created,**kwargs):
        if created:
            if instance.total_price <= 10000:
                abc = 0.01* (instance.total_price)
            else:
                abc = 0.75 * (instance.total_price)
            return abc

    post_save.connect(collect_points,sender=Order)

    def save(self,*args,**kwargs):
        self.points_gained = self.collect_points()
        super(Points, self).save(*args, **kwargs)

我尝试使用 Django 信号并覆盖保存功能来创建点。但是当我检查 db 时,点表中没有行,尽管已经下订单了。

OrderCreate API

class OrderSerializer(serializers.ModelSerializer):
    billing_details = BillingDetailsSerializer()
    order_items = OrderItemSerializer(many=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    #total_price = serializers.SerializerMethodField(source='get_total_price')
    class Meta:
        model = Order
        fields = ['id','user','ordered_date','order_status', 'ordered', 'order_items', 'total_price', 'billing_details']
        # depth = 1

   

   
    def create(self, validated_data):
        user = self.context['request'].user
        if not user.is_seller:
            order_items = validated_data.pop('order_items')
            billing_details = validated_data.pop('billing_details')
            order = Order.objects.create(user=user,**validated_data)
            BillingDetails.objects.create(user=user,order=order,**billing_details)
            for order_items in order_items:
                OrderItem.objects.create(order=order,**order_items)

            
            order.save()
            return order
        else:
            raise serializers.ValidationError("This is not a customer account.Please login as customer.")

【问题讨论】:

  • 用户是每次购买获得积分还是每次购买金额获得积分?
  • 每消费点数。我已经提到每个购买金额可以获得多少积分?你能帮我解决这个问题吗??
  • 我不建议不要节省价格。如果产品的价格发生变化,看起来用户支付了该金额,这是不正确的。
  • 我的建议是为订单创建创建一个保存后信号,然后我会更新用户的积分。这些点可以保存在用户模型上(如果您有自定义用户模型),否则为这些点创建一个单独的模型并向用户添加一对一的字段。
  • 我有一个自定义用户模型,但是在订单模型中计算价格后如何保存自定义用户模型中的积分?能不能写点东西(代码)给我看看??

标签: django database api django-models django-rest-framework


【解决方案1】:

此答案基于 cmets 和更新的代码。

我会在用户和积分模型之间建立关系,因为积分属于用户而不是订单。这也使您可以在同一用户再次订购时更新积分。

这会产生以下模型和保存后信号:

def update_points(sender, instance, created, **kwargs):
    if created:
        if instance.total_price <= 10000:
            points_gained = 0.01 * instance.total_price
        else:
            points_gained = 0.75 * instance.total_price

        try:
            # Check if user already has points and update if so
            points = Points.objects.get(user=instance.user)
            points.points_gained = points_gained
            points.save(update_fields=['points_gained'])
        except Points.DoesNotExist:
            # User does not have points yet, create points
            Points.objects.create(user=instance.user,
                                  points_gained=points_gained)


post_save.connect(update_points, sender=Order)


class Points(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=False, null=False)
    points_gained = models.IntegerField(default=0)

【讨论】:

  • 你好@Vincent,我试过你的代码,但是当我检查我的数据库时,points_gained 每次都是 0,好像除了 Points.DoesNotExist 之后的代码:你能再检查一次吗?
  • @SPDjango是创建订单后创建的积分对象?
  • 是的,Point 对象已创建,但 points_gained 值为零。
  • 如果创建了 points 对象并且 points_gained 的值为 0,这意味着您必须计算点数的逻辑导致为 0。所以 points_gained = 0.01 * instance.total_pricepoints_gained = 0.75 * instance.total_price 为 0 .sum([_.price for _ in self.order_items.all()]) 不知何故为 0。尝试调试它。
  • 我计算了总和并将其保存在订单字段中,它不是零,因为我调用了 orderdetails api,我可以看到价格。现在我认为 Order 是在创建 OrderItem api 之前创建的,因此最初在没有创建 OrderItem 对象时会传递一个信号。你能检查我的订单创建 api 吗?你会知道的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
相关资源
最近更新 更多