Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework: Disable field update after object is created

I'm trying to make my User model RESTful via Django Rest Framework API calls, so that I can create users as well as update their profiles.

However, as I go through a particular verification process with my users, I do not want the users to have the ability to update the username after their account is created. I attempted to use read_only_fields, but that seemed to disable that field in POST operations, so I was unable to specify a username when creating the user object.

How can I go about implementing this? Relevant code for the API as it exists now is below.

class UserSerializer(serializers.HyperlinkedModelSerializer):     class Meta:         model = User         fields = ('url', 'username', 'password', 'email')         write_only_fields = ('password',)      def restore_object(self, attrs, instance=None):         user = super(UserSerializer, self).restore_object(attrs, instance)         user.set_password(attrs['password'])         return user   class UserViewSet(viewsets.ModelViewSet):     """     API endpoint that allows users to be viewed or edited.     """     serializer_class = UserSerializer     model = User      def get_permissions(self):         if self.request.method == 'DELETE':             return [IsAdminUser()]         elif self.request.method == 'POST':             return [AllowAny()]         else:             return [IsStaffOrTargetUser()] 

Thanks!

like image 327
Brad Reardon Avatar asked Mar 02 '14 06:03

Brad Reardon


1 Answers

It seems that you need different serializers for POST and PUT methods. In the serializer for PUT method you are able to just except the username field (or set the username field as read only).

class UserViewSet(viewsets.ModelViewSet):     """     API endpoint that allows users to be viewed or edited.     """     serializer_class = UserSerializer     model = User      def get_serializer_class(self):         serializer_class = self.serializer_class          if self.request.method == 'PUT':             serializer_class = SerializerWithoutUsernameField          return serializer_class      def get_permissions(self):         if self.request.method == 'DELETE':             return [IsAdminUser()]         elif self.request.method == 'POST':             return [AllowAny()]         else:             return [IsStaffOrTargetUser()] 

Check this question django-rest-framework: independent GET and PUT in same URL but different generics view

like image 184
Andrei Kaigorodov Avatar answered Sep 20 '22 17:09

Andrei Kaigorodov