I am trying to generate a uniq OrderItem_ID during the order create api. But, it generates the above error as django.db.utils.IntegrityError:
The first API is always successful from the postman, but in the second call I tried changing different products for creating the order, but I am getting this unique id order.
I have to remove the order_items from the database, to create a new order_item object otherwise I get this unique error.
I am sending data like this.
My model:
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,)
My serializers:
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.")
In python shell, i tired this and it works fine
the problem is with
orderItem_ID = models.CharField(max_length=12,unique=True, editable=False, default=id_generator())
Here in the default, you're have assigned function call. Thus, it will only be evaluated once at the time of creation, .i.e., at first time you run makemigrations.
We need to have function references in the default values, this way it will be called each time a new instance is created.
Try replacing the line with
orderItem_ID = models.CharField(max_length=12,unique=True, editable=False, default=id_generator)
Note default=id_generator
and not default=id_generator()
.
Hope this answers your question. PS: you would be required to rerun the makemigrations and migrations commands to set this change into effect.