You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SerializerMethodField的get_user_permissions函数未调用,求技术解决方案

问题原因及解决办法

核心原因

SerializerMethodField 是只读字段,仅在序列化阶段(将模型对象转为响应数据)触发对应的get_xxx方法;而你当前的视图动作是处理PATCH/PUT请求,处于反序列化阶段(解析请求输入数据),这个阶段SerializerMethodField会被完全忽略,自然不会调用get_user_permissions,连print(1)都不会执行。

针对性解决方案

根据你的实际需求分两种情况处理:

情况1:仅需接收前端传来的权限数据执行移除操作

直接把user_permissions改成支持反序列化的字段类型,比如PrimaryKeyRelatedField:

class RemovePermissionsSerializer(serializers.ModelSerializer):
    # 改用支持接收输入的字段,many=True表示接收多个权限ID
    user_permissions = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=Permission.objects.all()
    )

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

这样在视图中调用serializer.validated_data.get("user_permissions")就能正常拿到前端传入的权限数据,无需get_user_permissions方法。

情况2:处理完移除操作后,需要返回用户更新后的权限数据

拆分输入、输出逻辑:用一个序列化器处理请求输入,另一个带SerializerMethodField的序列化器处理响应输出:

# 处理输入的序列化器
class RemovePermissionsInputSerializer(serializers.ModelSerializer):
    user_permissions = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=Permission.objects.all()
    )

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

# 处理输出的序列化器(保留你的SerializerMethodField)
class RemovePermissionsOutputSerializer(serializers.ModelSerializer):
    user_permissions = serializers.SerializerMethodField()

    def get_user_permissions(self, instance):
        print(1)
        # 你的自定义逻辑,比如返回权限的名称/编码等
        return [perm.codename for perm in instance.user_permissions.all()]

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

# 视图动作修改
@action(
    methods=["patch", "put"],
    detail=True,
    url_name="remove-permissions",
    url_path="remove-permissions"
)
def remove_permissions_request(self, request, pk):
    # 第一步:解析请求输入
    input_serializer = RemovePermissionsInputSerializer(data=request.data)
    input_serializer.is_valid(raise_exception=True)
    user = self.get_object()
    user_permissions = input_serializer.validated_data.get("user_permissions")
    User.remove_permissions(user, user_permissions)  # 执行移除逻辑

    # 第二步:序列化用户最新权限,返回响应
    output_serializer = RemovePermissionsOutputSerializer(user)
    return Response(output_serializer.data, status=status.HTTP_200_OK)

此时执行到序列化输出阶段,get_user_permissions就会被正常调用,print(1)也会输出。

内容的提问来源于stack exchange,提问作者eksoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:30:57