I'm looking for a way to use different serializers within a ModelViewSet depending on the request.user properties making the call.
Case 1: The request.user is the owner of the profile and must use the serializer called 'UserProfileOwnerSerializer' which allows a partial edit of their properties.
Case 2: request.user has full control rights over profiles properties and must therefore use 'UserProfileViewEditSerializer'
Case 3: request.user has only read rights on user profiles and must use 'UserProfileViewOnlySerializer' which sets all fields to readonly.
I created 3 permission checkers also used to check permissions within 'permissions.BasePermission':
def haveProfileOwnerRights(request, obj):
if (request.user.userprofile.id == obj.id):
return True
else:
return False
def haveProfileViewRights(request):
roleRightsProfileView = [
'MA',
'AM',
'ME',
'VI',
]
role = request.user.userprofile.role
if (role in roleRightsProfileView):
return True
else:
return False
def haveProfileViewEditRights(request):
roleRightsProfileViewEdit = [
'MA',
'AM',
'ME',
]
role = request.user.userprofile.role
if (role in roleRightsProfileViewEdit):
return True
else:
return False
class IsOwnerOrHaveProfileViewEditOrViewRight(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if (request.user.is_anonymous):
return False
if (haveProfileOwnerRights(request, obj)):
return True
if (haveProfileViewEditRights(request)):
return True
return False
class UserProfileViewSet(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated, IsOwnerOrHaveProfileViewEditOrViewRight
]
queryset = UserProfile.objects.all()
def get_serializer_class(self):
if haveProfileViewEditRights(self.request):
return UserProfileViewEditSerializer
if haveProfileViewRights(self.request):
return UserProfileViewOnlySerializer
#
# MISSING SERIALIZERS FOR 'UserProfileOwnerSerializer'
# I need to know here the content of the object to be serialized
#
To check if the serializer that I have to use for users who have 'haveProfileOwnerRights' I must be able to know the content of the object in order to pass it as a parameter to the 'haveProfileOwnerRights' function.
How can I get the object to be serialized inside 'get_serializer_class'?
Or is there a different approach that allows me to achieve the same result but in a different way?
Please save my brain :-)
CodePudding user response:
You can override get_serializer()
. It should receive the instance
as the first argument.
class UserProfileViewSet(viewsets.ModelViewSet):
def get_serializer(self, instance=None, *args, **kwargs):
if instance.type == "xxx":
serializer_class = # set it depending on your conditions
else:
serializer_class = self.get_serializer_class()
kwargs.setdefault('context', self.get_serializer_context())
return serializer_class(instance, *args, **kwargs)