Home > Enterprise >  SerializerMethodField's function get_fieldname is not being called
SerializerMethodField's function get_fieldname is not being called

Time:09-08

I have this Serializer

    class RemovePermissionsSerializer(serializers.ModelSerializer):
        user_permissions = serializers.SerializerMethodField()

        def get_user_permissions(self, instance):
            print(1)
            **logic**
            return data

        class Meta:
            model = User
            fields = [
                "user_permissions"
            ]

and a generic viewset with this action

@action(
        methods=["patch", "put"],
        detail=True,
        url_name="add-permissions",
        url_path="add-permissions"
    )
    def add_permissions_request(self, request, pk):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.get_object()
        user_permissions = serializer.validated_data.get("user_permissions")
        response = User.add_permissions(user, user_permissions)
        return Response(response, status=status.HTTP_200_OK)

the function get_user_permissions is not being called whatever I put in it, even print() is not showing anything, any help please?

CodePudding user response:

Here you use the serializer in the other way. A SerializerMethodField is read-only: since a function is always input to output. Here you are trying to work with it in the write direction.

This is one of the many reasons why using a SerializerMethodField is often not a good idea.

Usually it makes more sense to work with a sub-serializer, a PrimaryKeyRelatedField [drf-doc], or a SlugRelatedField [drf-doc].

You can for example use:

from django.contrib.auth.models import Permission


class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = ['__all__']


class RemovePermissionsSerializer(serializers.ModelSerializer):
    user_permissions = PermissionSerializer(source='permission', many=True)

    class Meta:
        model = User
        fields = ['user_permissions']

then you specify all the details of the permission, or you can work with a PrimaryKeyRelatedField or SlugRelatedField to let the user specify the primary key of the permission, or some other field ("slug"):

from django.contrib.auth.models import Permission


class RemovePermissionsSerializer(serializers.ModelSerializer):
    user_permissions = serializers.PrimaryKeyRelatedField(
        source='permission', many=True, queryset=Permission.objects.all()
    )

    class Meta:
        model = User
        fields = ['user_permissions']
  • Related