【问题标题】:KeyError: 'id' in django rest framework when trying to use update_or_create() methodKeyError:尝试使用update_or_create()方法时django rest框架中的'id'
【发布时间】:2021-12-30 06:05:32
【问题描述】:

我正在尝试使用 update_or_create() 方法更新 OrderItem 模型。 OrderItem 模型与 Order 模型具有多对一的关系,即外键。

我正在尝试使用 id 查询 orderitem 对象并使用默认值更新相关字段,如您所见,但出现此错误。

我的模型:

class Order(models.Model):    
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)   
    ordered_date = models.DateTimeField(auto_now_add=True)
    ordered = models.BooleanField(default=False)
    total_price = models.CharField(max_length=50,blank=True,null=True)
    #billing_details = models.OneToOneField('BillingDetails',on_delete=models.CASCADE,null=True,blank=True,related_name="order")

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

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

class OrderItem(models.Model):
    #user = models.ForeignKey(User,on_delete=models.CASCADE, blank=True)
    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')

我的看法:

class UpdateOrderView(UpdateAPIView):
    permission_classes = [AllowAny]
    queryset = Order.objects.all()
    serializer_class = OrderUpdateSerializer

我的序列化器:

class OrderUpdateSerializer(serializers.ModelSerializer):
    order_items = OrderItemUpdateSerializer(many=True)
    billing_details = BillingDetailsSerializer()

    class Meta:
        model = Order
        fields = ['id','ordered','order_status','order_items','billing_details']


    def update(self, instance, validated_data):
        instance.order_status = validated_data.get('order_status')
        instance.ordered = validated_data.get('ordered')

        #billing_details_logic

        billing_details_data = validated_data.pop('billing_details',None)
        if billing_details_data is not None:
            instance.billing_details.address = billing_details_data['address']
            instance.billing_details.save()


        #order_items_logic
        instance.save()

        order_items_data = validated_data.pop('order_items')
        # print(order_items_data)
        #instance.order_items.clear()
        for order_items_data in order_items_data:
            oi, created = OrderItem.objects.update_or_create(
                id= order_items_data['id'],
                defaults={

                    'quantity' : order_items_data['quantity'],
                    'order_item_status': order_items_data['order_item_status']

                }
            )
            
        super().update(instance,validated_data)
        return oi

更新的序列化程序:

for order_item_data in order_items_data:
            oi, created = instance.order_items.update_or_create(
                id= order_item_data['id'],
                defaults={

                    'quantity' : order_item_data['quantity'],
                    'order_item_status': order_item_data['order_item_status']

                }
            )

order_items 数据是这样发送的。

【问题讨论】:

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


    【解决方案1】:

    order_items_datalist。 然后使用相同的变量名对其进行迭代。

            for order_items_data in order_items_data:
    

    只需将其重命名为类似

        for order_data in order_items_data:
    

    你的order_data中会有一个id

    【讨论】:

    • 是的,我将它重新设置为 order_item_data,但得到了同样的错误。任何想法?? @汤姆
    • 刚刚添加。你可以看看。
    • 您确定order_items_data 是字典列表而不是OrderItem 列表吗?如果是这样,您必须通过order_item_data.id 访问id,而不是order_item_data['id']
    • 是的,它是一个字典列表,因为一个订单可以有多个 order_items。在邮递员中,我正在发送这样的数据。 “order_items”:[{}、{}、{}...]。但现在,我只发送一个 {}。
    • 是的,但在 validated_data 中,我认为它已经映射到了 ORM。
    【解决方案2】:

    我也没有在 OrderedDict 上获得 id,所以我在序列化程序上添加了一个 id = serializers.IntegerField(required=False) 并将 id 放入 update_or_create 方法中:

      for obj in data:
          Model.objects.update_or_create(
              pk=obj.get('id', None), ...
          )
    

    【讨论】:

      猜你喜欢
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2020-05-30
      • 2020-11-23
      相关资源
      最近更新 更多