(1062, «Дубликат записи ’81CLZECZRW’ для ключа ‘orders_orderitem.orders_orderitem_orderItem_ID_7d6cd69b_uniq'») на платформе Django Rest

#django #api #django-rest-framework #postman #unique

Вопрос:

Я пытаюсь сгенерировать идентификатор uniq OrderItem_ID во время api создания заказа. Но он генерирует вышеуказанную ошибку как django.db.utils.Ошибка целостности:

Первый api всегда успешен у почтальона, но во время второго вызова я попытался изменить различные продукты для создания заказа, но я получаю этот уникальный идентификатор заказа.

Я должен удалить order_items из БД , чтобы создать новый объект 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 я устал от этого, и это отлично работает

введите описание изображения здесь

Ответ №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 и миграции, чтобы это изменение вступило в силу.

Комментарии:

1. Ух ты, это сработало. Да, я думаю, что это уникально, когда я запускал makemigrations. Вот почему я был сбит с толку, так как мне пришлось дважды запускать миграции, одну для поля addfield, а другую для поля alterfield, когда я создавал поле. Спасибо @VJ Magar

Ответ №2:

Ошибка проверки происходит отсюда:

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

Добавьте orderItem_ID в OrderItemSerializer и попробуйте отправить orderItem_ID в «order_items» с уникальным значением для каждой записи.

Что касается этого: по умолчанию=id_generator()

Проверьте, что эта функция генерирует при каждом попадании, возможно, она сохраняет одно и то же значение каждый раз, что вызывает ошибку.

Комментарии:

1. Я добавил orderItem_ID в OrderItemSerializer, но я получаю ошибку. Я тоже попытался удалить, но та же ошибка. В postman он показывает тот же идентификатор и говорит об уникальной ошибке. Я застрял @Neeraj

2. вы проверяли, какие значения отправляются в полезной нагрузке или во время генерации для orderItem_ID?

3. И что именно делает эта функция? id_generator()

4. Да @Neeraj, он будет генерировать одно и то же значение для каждого экземпляра элемента заказа. Я поделился своим ответом, объяснив причину.

5. Ах, справедливая точка зрения @VJ Magar, я этого не заметил. Сарой в следующий раз вам также следует проверить, что отправляют вызовы функций. Попробуйте использовать режим отладчика, и вы гораздо лучше поймете процесс