Home > OS >  Different serializers based on user object rights
Different serializers based on user object rights

Time:07-01

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) 

  • Related