如何在序列化器中分配现有的嵌套对象?

时间:2019-04-29 19:31:24

标签: python django serializer

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

这里的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类相关的每个字段。如何解决?也许有一种更简单的处理方式?

2 个答案:

答案 0 :(得分:0)

您应该能够将参数直接传递给Membership.objects.create调用:

def create(self, validated_data):
    return Membership.objects.create(
        **validated_data,
        user_id=validated_data.pop('user'),
        club_id=validated_data.pop('club'),
        inClubRole_id=validated_data.pop('inClubRole')
    )

我相信您也可以通过将字段设置为:

fields=('user_id', 'club_id', 'inClubRole_id')

并将JSON更改为:

{
  "user_id": 1,
  "club_id": 1,
  "inClubRole_id": 4
}

答案 1 :(得分:0)

我已经处理了一些差异。我将 ... Serializer 字段交换为 PrimaryKeyRelatedField ,因此我仅使用相关对象的ID即可更新和创建Membership对象。我还重写了to_representation(self,value)方法,因此在 get 请求中,我可以用嵌套数据填充相关字段。这是我的最终解决方案:

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