I have the following models:
# models.py
class NPSUser(AbstractBaseUser, TimeStampedModel):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
class Account(models.Model):
user = models.OneToOneField(NPSUser, related_name='%(class)s_role', primary_key=True)
class Meta:
abstract = True
class Director(Account):
tenant = models.OneToOneField(Tenant, related_name='director')
With the corresponding serializers:
# serializers.py
class NPSUserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=False)
confirm_password = serializers.CharField(write_only=True, required=False)
class Meta:
model = NPSUser
fields = ('id', 'email', 'created', 'modified', 'first_name',
'last_name', 'password', 'confirm_password', 'director_role',
'manager_role', 'employee_role', 'projectmanager_role',
'collector_role')
read_only_fields = ('id', 'created', 'modified', 'director_role',
'manager_role', 'employee_role', 'projectmanager_role',
'collector_role')
def create(self, validated_data):
return NPSUser.objects.create(**validated_data)
def update(self, instance, validated_attrs):
instance.email = validated_attrs.get('email', instance.email)
instance.first_name = validated_attrs.get('first_name', instance.first_name)
instance.last_name = validated_attrs.get('last_name', instance.last_name)
instance.save()
# password validation here...
return instance
class DirectorSerializer(serializers.ModelSerializer):
user = NPSUserSerializer()
class Meta:
model = Director
def create(self, validated_data):
user_data = validated_data.pop('user')
user = NPSUser(**user_data)
user.set_password(user_data['password'])
user.save()
director = Director.objects.create(user=user, **validated_data)
return director
I use viewset.ModelViewSet
in the views.py and if I already have a user with the name 'John' and 'email@gmail.com' email in the database and I make a PUT request to update the NPSUser through its Director relationship, like this: PUT /api/v1/directors/1/ {id: 1, tenant: 1, user: {id: 1, first_name: 'Jane', last_name: 'King', email: 'email@gmail.com'}}
the following error is returned from the server: {"user":{"email":["This field must be unique."]}}
, which means that serializer.is_valid()
does not pass.
And the proper question is: How can I update the NPSUser object that has a unique=True
field from another object that has a relationship field with NPSUser using serializers in Django REST Framework?