首页 > 解决方案 > 如何在序列化程序中分配现有的嵌套对象?

问题描述

我有包含 3 个 ForeginKey 字段的 Membership 类。这些 FK 总是必须引用已经存在的对象,所以我想知道如何简化MembershipSerializer 中的创建更新方法,以便仅使用请求中传递的键来分配这些字段。

这是 MembershipSerializer 类代码:

class MembershipSerializer(serializers.ModelSerializer):
user = UserSerializer(many=False)
club = ClubSerializer(many=False)
inClubRole = InClubRoleSerializer(many=False)
class Meta:
    fields=(
        'user',
        'club',
        'inClubRole',
        )

    model = Membership

def create(self, validated_data):
    print(validated_data)
    user_data = User.objects.get(id=validated_data.pop('user'))
    club_data = Club.objects.get(id=validated_data.pop('club'))
    inClubRole_data = InClubRole.objects.get(id=validated_data.pop('inClubRole'))
    instance = Membership.objects.create(**validated_data)
    instance.user=user_data
    instance.club = club_data
    instance.inClubRole = inClubRole_data
    return instance

由于 User、Club 和 InClubRole 模型已经存在,我想通过像这样传递主键来简化 Membership 类的 POST 和 UPDATE:

{
"user": 1,
"club": 1,
"inClubRole": 4
}

然而create方法仍然期望传递与 User、Club 和 InClubRole 类相关的每个字段。如何解决?或者也许有更简单的方法来处理它?

标签: pythondjangoserialization

解决方案


我已经处理了它有点不同。我将...Serializer 字段交换为PrimaryKeyRelatedField,因此我能够仅使用相关对象的 ID 更新和创建 Membership 对象。我还重写to_representation(self,value)了方法,以便获取请求我可以用嵌套数据填充相关字段。这是我的最终解决方案:

class MembershipSerializer(serializers.ModelSerializer):

user = serializers.PrimaryKeyRelatedField(queryset = User.objects.all())
club = serializers.PrimaryKeyRelatedField(queryset = Club.objects.all())
inClubRole = serializers.PrimaryKeyRelatedField(queryset = InClubRole.objects.all())
class Meta:
    fields=(        
        'user',
        'club',
        'inClubRole',
       )        
    model = Membership

def to_representation(self, value):
    data = super().to_representation(value)  
    user_data = UserSerializer(value.user)
    club_data = ClubSerializer(value.club)
    inClubRole_data = InClubRoleSerializer(value.inClubRole)
    data['user'] = user_data.data
    data['club'] = club_data.data
    data['inClubRole'] = inClubRole_data.data
    return data

推荐阅读