Search code examples
djangoserializationdjango-rest-frameworkpostmanone-to-one

This field must be unique error in postman in OnetoOneField in Django Rest Framework


I am trying to update Customer Profile also updating main Customuser first_name and last_name field at the same time using nested serialization. But I am getting customer field must be unique error.

I have posted the pics here.

enter image description here

enter image description here

My models:

class CustomUser(AbstractUser):
    # username = None
    first_name = models.CharField(max_length=255, verbose_name="First name")
    last_name = models.CharField(max_length=255, verbose_name="Last name")
    email = models.EmailField(unique=True)
    
    is_seller = models.BooleanField(default=False)
    is_customer = models.BooleanField(default=False)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["first_name", "last_name"]

    objects = CustomUserManager()

    def __str__(self):
        return self.email


class Customer(models.Model):
    customer = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
    full_name = models.CharField(max_length=100, blank=True)
    phone_num = models.CharField(max_length=50, blank=True)
    #dob = models.CharField(max_length=255,blank=True,null=True)
    region = models.CharField(max_length=255, blank=True,null=True)
    city = models.CharField(max_length=255, blank=True, null=True)
    area = models.CharField(max_length=255,blank=True,null=True)
    address = models.CharField(max_length=255, blank=True, null=True)


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

My serializers:

class CustomerProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'
        # depth = 1


class CustomerUpdateSerializer(serializers.ModelSerializer):
    customer = CustomerProfileSerializer()
    class Meta:
        model = User
        fields = ('id', "first_name", "last_name",'customer')

    def update(self,request, instance, validated_data):
        user = self.request.user
        instance.user.first_name=user.get('first_name')
        instance.user.last_name = user.get('last_name')
        instance.user.save()
        customer_data = validated_data.pop('customer',None)
        if customer_data is not None:
            instance.customer.region = customer_data['region']
            instance.customer.city = customer_data['city']
            instance.customer.area = customer_data['area']
            instance.customer.address = customer_data['address']
            instance.customer.save()
        return super().update(instance,validated_data)

My views:

class CustomerUpdateView(UpdateAPIView):
    permission_classes = [IsAuthenticated]
    queryset = User.objects.all()
    serializer_class = CustomerUpdateSerializer

The url is visible in postman put request. I have sent the raw json data in the postman, but it throws this error. How to update those 4 fields in customer and 2 fields (first_name and last_name) from User model??


Solution

  • My code worked after I made some changes to the serializer.

    Here is the working code:

    class CustomerUpdateSerializer(serializers.ModelSerializer):
        customer = CustomerProfileSerializer(many=False)
        class Meta:
            model = User
            fields = ('id', "first_name", "last_name",'customer')
            depth = 1
    
        def update(self, instance, validated_data):
            user = self.context['request'].user
            user.first_name = validated_data.get('first_name')
            user.last_name = validated_data.get('last_name')
            user.save()
            customer_data = validated_data.pop('customer',None)
            if customer_data is not None:
                instance.customer.region = customer_data['region']
                instance.customer.city = customer_data['city']
                instance.customer.area = customer_data['area']
                instance.customer.address = customer_data['address']
                instance.customer.save()
            return super().update(instance,validated_data)
    

    Its because I was using instance of user and same instance to customer model. Now, I get the fields first_name and last_name separately and use instance for customer only.It worked.