Reputation: 91
I want to make it so a user is able to update only certain attributes with a PUT request in my Django Rest API. As an example, if I had the following model and only wanted the user to be able to update their first and last name, how would I go about doing this?
models.py:
class User(models.Model):
email = models.EmailField('email address', unique = True)
first_name = models.TextField(max_length = 10)
last_name = models.TextField(max_length = 20)
(noting that they should not be able to change the 'id' field either which is automatically set)
serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'email', 'first_name', 'last_name']
views.py:
class SingleUser(APIView):
def put(self, request, user_id):
user = User.objects.get(pk = user_id)
serializer = UserEditSerializer(user, data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status = status.HTTP_200_OK)
return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)
What is the best way to enforce that users can only change a subset of these attributes?
Thanks, Grae
Upvotes: 1
Views: 1447
Reputation: 427
You can use the read_only_fields, a serializer's attribute.
Another approach is to use a "serializer per action"
Upvotes: 0
Reputation: 88549
Create a separate serializer and use it
# serializers.py
class UserPutSerializer(serializers.ModelSerializer): # new serializer class
class Meta:
model = User
fields = ['first_name', 'last_name'] # define required fields
#views.py
class SingleUser(APIView):
def put(self, request, user_id):
user = User.objects.get(pk=user_id)
serializer = UserPutSerializer(user, data=request.data) # use new serializer here
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Upvotes: 2
Reputation: 5405
You can set read-only fields on a serializer:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'email', 'first_name', 'last_name']
read_only_fields = ['id', 'email']
Make sure to set your serializer to partial in the put function:
serializer = UserEditSerializer(user, data = request.data, partial=True)
You could also omit fields from the serializer altogether, which will make the fields not available to the user at all.
Upvotes: 3