Reputation: 886
i'm using Django 1.11 and the Django Rest Framework in order to create an API, where a user can create and update an employee which is related to the django user model.
The stripped down code i've got looks like this:
I've got this model:
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employee')
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
these two viewsets:
class UserViewSet(viewsets.ModelViewSet):
serializer_class = serializers.UserSerializer
permission_classes = [permissions.IsAuthenticated]
and
class EmployeeViewSet(viewsets.ModelViewSet):
serializer_class = serializers.EmployeeSerializer
permission_classes = [permissions.IsAuthenticated]
and these two serializers:
class UserSerializer(serializers.HyperlinkedModelSerializer)
class Meta
models = User
fields = ('url', 'id', 'username', 'email', 'is_staff', 'first_name', 'last_name', 'password')
read_only_field = ('id',)
def validate(self, data)
# ... Check if data is valid and if so...
return data
and
class EmplyoeeSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
class Meta:
model = Employee
field = ('url', 'uuid', 'user')
read_only_field = ('uuid')
def validate(self, data):
return data
def create(self, validated_data):
user = User(**validated_data['user'])
user.save()
employee = Employee(user=user)
employee.save()
return employee
def update(self, employee, user):
employee.user.username = user.username
employee.user.email = user.email
employee.user.first_name = user.first_name
employee.user.last_name = user.last_name
employee.user.is_staff = user.is_staff
# ... Check if password has changed, and if so...
employee.user.set_password(user.password)
employee.user.save()
employee.save()
return employee
also i've got these two routers in my urls.py
router = routers.DefaultRouter()
router.register(r'api/user', views.UserViewSet, base_name='user')
router.register(r'api/employee', views.UserViewSet, base_name='employee')
Creating and updating an instance of user is no problem.
I can also create an employee which in return will create an user and then an employee assigend to that user.
I can even update the username of the employee and the user will get updated too,
but i can't update first_name, last_name, email, is_staff and password.
DRF keeps telling me that the username is already taken, but when i change the username and other information like first_name and last_name and then send a PUT request to the server, the employee and associated user instance are getting updated properly.
What am i missing?
Why can't i update the employees user instance like i can update the normal user instance when i'm at the user api endpoint? :/
Thanks in advance,
any help would be appreciated.
Upvotes: 3
Views: 720
Reputation: 886
Finally i found out what i was missing.
The UserSerializers adds django.contrib.auth.validators.UnicodeUsernameValidator
and UniqueValidator
to the field username which gets checked every time i do a put request.
Adding validators = []
to the Meta Class of UserSerializer solved my problem.
Upvotes: 0