Cannot update model because "id already exists"

Viewed 419

I am new to Django and I am trying to use update_or_create in the serializer.create().

However, when I send a request with an existing id for customer, gift or subscription, it shows "id already exists" and does not proceed.

What am I doing wrong here? Or is there a completely different way to do this?

class SubscriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subscription
        fields = ['id', 'plan_name', 'price']


class GiftSerializer(serializers.ModelSerializer):
    class Meta:
        model = Gift
        fields = ['id', 'plan_name', 'price', 'recipient_email']


class CustomerSerializer(serializers.ModelSerializer):
    subscription = SubscriptionSerializer(required=False)
    gifts = GiftSerializer(many=True)

    class Meta:
        model = Customer
        fields = [
            'id', 'first_name', 'last_name', 'address_1', 'address_2', 'city', 'state', 'postal_code', 'subscription',
            'gifts']


class RecordSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer(required=True)

    class Meta:
        model = Record
        fields = ['customer']

    def create(self, validated_data):
        customer_data = validated_data.pop('customer')

        subscription_data = customer_data.pop('subscription')
        gifts_data = customer_data.pop('gifts')

        customer, created = Customer.objects.update_or_create(**customer_data)

        Subscription.objects.update_or_create(customer=customer, **subscription_data)

        for gift_data in gifts_data:
            Gift.objects.update_or_create(customer=customer, **gift_data)

        record, created = Record.objects.update_or_create(customer=customer, **validated_data)

        return record

Error is HTTP 400 Bad request

{
    "customer": {
        "id": [
            "customer with this id already exists."
        ],
        "subscription": {
            "id": [
                "subscription with this id already exists."
            ]
        },
        "gifts": [
            {
                "id": [
                    "gift with this id already exists."
                ]
            },
            {
                "id": [
                    "gift with this id already exists."
                ]
            }
        ]
    }
}
1 Answers

update_or_create needs to know which fields are unique, and which fields should be updated on an IntegrityError. To specify the fields to update, add your arguments via the defaults keyword.

For example, your customer model might look like this:

customer_id = customer_data.pop('id')

customer, created = Customer.objects.update_or_create(
    id = customer_id, 
    defaults = customer_data,
)
Related