【问题标题】:How to calculate the price of Order using (sum of) OrderItems prices in django rest framework如何在django rest框架中使用(总和)OrderItems价格计算订单价格
【发布时间】:2021-04-05 07:42:48
【问题描述】:

我可以使用 @property 装饰器计算 OrderItem 模型的价格,但在创建订单对象时无法计算 Order 模型的总价格。

当我调用 post api 来创建订单时,没有错误,但我没有在 api 响应中得到 total_price。

我的模型:

class Order(models.Model):
    
    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)
    

#logic to calculate the total_price, and its not working

    @property
    def total_price(self):
        return sum([_.price for _ in self.order_items_set.all()]) #realted name is order_items

    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)



    #total_item_price = models.PositiveIntegerField(blank=True,null=True,default=0)

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

#Logic to calculate the total_item_price, it works.

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

我的序列化器:

Class OrderItemSerializer(serializers.ModelSerializer):    
    order = serializers.PrimaryKeyRelatedField(read_only=True)
    #price = serializers.ReadOnlyField()
    class Meta:
        model = OrderItem
        fields = ['id','order','orderItem_ID','item','order_variants', 'quantity','order_item_status','price']
        # depth = 1

class OrderSerializer(serializers.ModelSerializer):
    billing_details = BillingDetailsSerializer()
    order_items = OrderItemSerializer(many=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    # total_price = serializers.Field()
    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)
            
            return order
        else:
            raise serializers.ValidationError("This is not a customer account.Please login as customer.")

【问题讨论】:

  • 我已将该属性字段放入我的序列化程序中。我猜这应该足够了,因为在创建 OrderItem 价格时,我也做了同样的事情。检查我的 OrderItemSerializer,我只是把价格。
  • 顺便说一句,您的相关名称不同 order_itemsorder_items_set 。尝试使用相同的相关名称
  • 在两个地方取相同的相关名称`related_name=order_items_set'
  • 请参考 > this
  • this你的相关名称不同

标签: django api django-rest-framework postman response


【解决方案1】:

试试这个,

class OrderItemSerializer(serializers.ModelSerializer):    
    order = serializers.PrimaryKeyRelatedField(read_only=True)
    price = serializers.FloatField(read_only=True)

    class Meta:
        model = OrderItem
        fields = ['id','order','orderItem_ID','item','order_variants', 'quantity','order_item_status','price']
        # depth = 1

class OrderSerializer(serializers.ModelSerializer):
    billing_details = BillingDetailsSerializer()
    order_items = OrderItemSerializer(many=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    total_price = serializers.FloatField(read_only=True)

    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)
            
            return order
        else:
            raise serializers.ValidationError("This is not a customer account.Please login as customer.")

【讨论】:

  • 不,它没有用。在创建 OrderItem 价格时,我也这样做了。签入我的 OrderItemSerializer,我只是输入价格
猜你喜欢
  • 2014-03-29
  • 2020-05-17
  • 1970-01-01
  • 2015-10-18
  • 2016-08-15
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多