【问题标题】:(1062, "Duplicate entry '81CLZECZRW' for key 'orders_orderitem.orders_orderitem_orderItem_ID_7d6cd69b_uniq'") on Django Rest Framework(1062,“重复条目 '81CLZECZRW' 键 'orders_orderitem.orders_orderitem_orderItem_ID_7d6cd69b_uniq'”)在 Django Rest 框架上
【发布时间】:2021-06-29 01:58:12
【问题描述】:

我试图在订单创建 api 期间生成一个 uniq OrderItem_ID。但是,它会生成上述错误为 django.db.utils.IntegrityError:

邮递员的第一个 api 总是成功的,但在第二个调用中,我尝试更改不同的产品来创建订单,但我得到了这个唯一的 id 订单。

我必须从 db 中删除 order_item 以创建一个新的 order_item 对象,否则我会收到此唯一错误。

我正在发送这样的数据。

我的模特:

import random
import string
# Create your models here.

def id_generator(size=10, chars=string.ascii_uppercase + string.digits):
   return ''.join(random.choice(chars) for _ in range(size))

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)
    total_price = models.CharField(max_length=50,blank=True,null=True)
    
    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,unique=True, 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,)

我的序列化器:

class OrderSerializer(serializers.ModelSerializer):

    billing_details = BillingDetailsSerializer()
    order_items = OrderItemSerializer(many=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    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.")

在 python shell 中,我厌倦了这个,它工作正常

【问题讨论】:

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


    【解决方案1】:

    问题出在

    orderItem_ID = models.CharField(max_length=12,unique=True, editable=False, default=id_generator())
    

    默认情况下,您已分配函数调用。因此,它只会在创建时评估一次,即在您第一次运行 makemigrations 时。

    我们需要在默认值中有函数引用,这样每次创建新实例时都会调用它。

    尝试用

    替换该行
    orderItem_ID = models.CharField(max_length=12,unique=True, editable=False, default=id_generator)
    

    注意default=id_generator 而不是default=id_generator()

    希望这能回答您的问题。 PS:您需要重新运行 makemigrations 和 migrations 命令才能使此更改生效。

    【讨论】:

    • 哇,它成功了。是的,当我运行 makemigrations 时,我认为它是独一无二的。这就是为什么我很困惑,因为我必须运行两次 makemigrations,一次用于 addfield,另一次用于创建字段时的字段 alterfield。谢谢@VJ Magar
    【解决方案2】:

    验证错误来自这里:

    orderItem_ID = models.CharField(max_length=12,unique=True, editable=False, default=id_generator())
    

    在 OrderItemSerializer 中添加 orderItem_ID 并尝试在“order_items”中发送 orderItem_ID,并在每个帖子上使用唯一值。

    至于这个:default=id_generator()

    检查此函数在每次点击时生成的内容,可能每次都保存相同的值导致错误。

    【讨论】:

    • 我已在 OrderItemSerializer 中添加了 orderItem_ID,但出现错误。我也尝试删除,但同样的错误。在邮递员中,它显示相同的 ID 并表示唯一错误。我被卡住了@Neeraj
    • 您是否检查了在有效负载中发送的值或在 orderItem_ID 生成时发送的值?
    • 这个函数到底是做什么的? id_generator()
    • 是的@Neeraj,它将为订单项的每个实例生成相同的值。我已经分享了我的答案,解释了原因。
    • 啊,公平点@VJ Magar,没注意到。 Saroj 下次您还应该检查 func 调用发送的内容。尝试使用调试器模式,您会更好地理解流程
    猜你喜欢
    • 1970-01-01
    • 2011-11-11
    • 2012-07-23
    • 2013-09-30
    • 2015-04-26
    • 1970-01-01
    • 2019-07-21
    • 2017-08-07
    相关资源
    最近更新 更多