首页 > 解决方案 > AttributeError:“QuerySet”对象在 Django 休息框架中没有属性“活动”

问题描述

我正在尝试在 Django Rest 框架中实现优惠券代码功能。当用户尝试购买产品并希望使用商品上显示的优惠券代码时,用户应该能够根据该优惠券代码获得折扣。优惠券应该是有效的,即应该在有效期内并且应该是有效的。但是,当我尝试在不发送优惠券代码的情况下从邮递员处制作订单对象时,出现以下错误。

AttributeError:“QuerySet”对象没有“活动”属性

在使用优惠券代码功能之前,我可以下订单。

我的模型:

class Coupons(models.Model):
    product = models.ForeignKey(Product,on_delete=models.CASCADE,
                                blank=True,null=True,related_name="coupons")
    code = models.CharField(max_length=50,unique=True)
    valid_form = models.DateField()
    valid_till = models.DateField()
    active = models.BooleanField(default=False)
    discount = models.IntegerField(default=0)

    def __str__(self):
        return self.code

订购型号:

在这里,价格的每一个计算都完成了。

class Order(models.Model):
   
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
    order_ID = models.CharField(max_length=12, editable=False, default=id_generator)
    #order_items = models.ManyToManyField('OrderItem',blank=True, null=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)
    current_points = models.FloatField(default=0)
    total_price = models.FloatField(blank=True,null=True)
    point_spent = models.FloatField(default=0)
    coupon_code = models.CharField(max_length=15, blank=True, null=True)


    def final_price(self):
        total = sum([_.price_1 for _ in self.order_items.all()])
        total -= Decimal(self.price_of_points)
        dis = self.price_of_coupon
        print(dis)
        total = total - dis
        return total

    @property
    def price_of_coupon(self):
        coupon_code = self.coupon_code
        items = OrderItem.objects.filter(order=self.id)
        coupon_query = Coupons.objects.filter(code=coupon_code)
        if coupon_query.active is True:
            if coupon_query.valid_form <= _datetime.date.today() and coupon_query.valid_till <= _datetime.date.today():
                coupon_discount = coupon_query.discount
                for item in items:
                    if item.order == coupon_query.id:
                        return coupon_discount
            else:
                return coupon_query.discount
        else:
            return coupon_query.discount


    @property
    def price_of_points(self):
        point_spent = self.point_spent

        if point_spent == 0:
            return 0.0
        elif point_spent <= 10000.0 and point_spent >0:
            return 10.0
        else:
            return 75.0

    def save(self, *args, **kwargs):
        self.total_price = self.final_price()
        super(Order, self).save(*args, **kwargs)

这里错误显示在if coupon_query.active is True:但我在优惠券模型中有活动字段。我不知道是什么问题。

我的序列化器:

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')
    coupon_code = serializers.CharField(required=False)
    class Meta:
        model = Order
        fields = ['id','user','ordered_date','order_status','order_ID', 'ordered', 'order_items',
                  'total_price','point_spent','coupon_code', '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)
            ordered = validated_data.get('ordered')
            order.ordered = True
            order.save()
            return order
        else:
            raise serializers.ValidationError("This is not a customer account.Please login as customer.")

标签: pythondjangoapidjango-rest-frameworkdjango-queryset

解决方案


您必须使用get而不是filter. 因为,过滤返回记录列表并get仅返回一条记录。

还要记住,如果有多个记录具有相同的代码,那么get会引发错误。所以请确保您的数据库不存储重复的代码。

试试这样:

coupon_query = Coupons.objects.get(code=coupon_code)
  

更好的方法是使用方法get_object_or_404

像这样

coupon_query = get_object_or_404(Coupons, code=coupon_code) 

如果您不使用get_object_or_404方法,那么如果在代码中没有找到记录,它将触发您的服务器错误。

如果用户不想添加优惠券代码,那么您必须先处理一些其他条件

我还注意到您稍后再次比较日期,这不是最好的方法。

所以最好的,你试试这样

coupon_query = Coupons.objects.filter(code=coupon_code, valid_from__get=datetime.today(), valid_till__lt=datetime.today())

if couon_query.exists():
    validated_couopon = coupon_query.first()
else:
    raise ValidationError("Your Couon not valid")

推荐阅读