Django user DRF user
I am trying to create an api using Django-Rest-Framework (DRF) for CRUD a User. I managed to create and read the user, but for some reason the update won't work. It looks like it is trying to create a user rather than update it as it responds with a "username already exists" error. When I try to submit an email that is not already in the database, it just creates a new user. Does anyone know why this is happening?
Here is my User Serializer:
class UserSerializer(FriendlyErrorMessagesMixin, serializers.ModelSerializer):
password = serializers.CharField(
max_length=128,
min_length=8,
write_only=True
)
class Meta:
model = User
fields = ('username',
'email',
'password',
'name',
'house_number',
'address_line_one',
'address_line_two',
'address_line_three',
'city',
'postcode',
'phone_number')
read_only_fields = ('date_created', 'date_modified', 'username')
def update(self, instance, validated_data):
password = validated_data.pop('password', None)
for (key, value) in validated_data.items():
setattr(instance, key, value)
if password is not None:
instance.set_password(password)
instance.save()
return instance
and here is my opinion:
class UserRetrieveUpdateAPIView(RetrieveUpdateAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = UserSerializer
def retrieve(self, request, *args, **kwargs):
serializer = self.serializer_class(request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
def update(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
source to share
In the view, you must pass an Serializer
instance to update as the first argument, otherwise a new object will be created.
To update an authenticated user, follow these steps:
def update(self, request, *args, **kwargs):
serializer = self.serializer_class(request.user, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
In general, you can use or override the get_object
(from GenericAPIView
) method to get the correct instance; instead of reimplementing both retrieve
and update
.
source to share