在Django rest serializer中为嵌套值创建序列化器

时间:2016-02-05 03:27:49

标签: python json django serialization django-rest-framework

我正在尝试将我的django项目与来自mailchimp的api集成,以将用户添加到我需要以下列格式生成一些json的列表中:

{
  "email_address": "EMAIL",
  "status": "subscribed",
  "merge_fields": {
    "FNAME": "FIRST_NAME",
    "LNAME": "SURNAME"
  },

可悲的是,我正在与嵌套的merge_field进行一些斗争。我希望以下工作:

class MergeSerializer(serializers.Serializer):
    FNAME = serializers.SerializerMethodField('get_first_name')
    LNAME = serializers.SerializerMethodField('get_surname')

    def get_first_name(self, obj):
        return obj.first_name

    def get_surname(self, obj):
        return obj.surname

class CreateContactSerializer(serializers.Serializer):
    email_address = serializers.EmailField()
    status = serializers.SerializerMethodField('get_alternative_status')
    merge_fields = MergeSerializer(read_only=True)

    def get_alternative_status(self, obj):
        return "subscribed"

这只会生成一些带有email_address和状态的json,并完全忽略merge_fields。几个小时后,我完全不知道下一步该尝试什么。有人知道如何解决这个问题吗?

由于我认为marshmallow框架的文档更清晰一点,我也尝试了它们的包,然而这种结果完全相同(因此忽略了我的merge_fields):

class MergeFieldsSchema(Schema):
    FNAME = fields.String(attribute="first_name")
    LNAME = fields.String(attribute="surname")


class CreateContactSerializer(Schema):
    merge_fields = fields.Nested(MergeFieldsSchema)
    email_address = fields.String()
    status = fields.Constant("subscribed")

1 个答案:

答案 0 :(得分:3)

您没有这样说,但我假设surname和first_name也是模型上与email_address相同的对象的一部分,这就是嵌套序列化器不起作用的原因(因为嵌套序列化器用于外键)。如果不是这种情况,请将模型添加到OP。

因为您只想自定义输出,所以可以在主CreateContactSerializer上使用序列化方法:

class CreateContactSerializer(serializers.Serializer):
    email_address = serializers.EmailField()
    status = serializers.SerializerMethodField('get_alternative_status')
    merge_fields = serializers.SerializerMethodField('get_merge_fields')

    def get_alternative_status(self, obj):
        return "subscribed"

    def get_merge_fields(self, obj):
        return {
            "FNAME": obj.first_name,
            "LNAME": obj.surname
        }

如果需要,您甚至可以重复使用已经使用过的序列化程序

def get_merge_fields(self, obj):
    serializer = MergeSerializer(obj)
    return serializer.data;

不要忘记将merge_fields添加到fields