简体   繁体   English

django rest 框架 - 将相关对象字段序列化为平面 json dict

[英]django rest framework - serializing related object fields to a flat json dict

The DRF docs describe a way to create nested serializers that can produce dicts like this: DRF 文档描述了一种创建嵌套序列化程序的方法,该序列化程序可以生成如下所示的字典:

{
    "field1": "val1",
    "field2": "val2",
    "related_obj": {
        "related_obj_field_1": "val1",
        "related_obj_field_2": "val2",
    }
}

but what if I want to create a flat dict that would include all related object fields at the same level as the parent object fields?但是,如果我想创建一个包含与父对象字段处于同一级别的所有相关对象字段的平面字典,该怎么办? Like so:像这样:

{
    "field1": "val1",
    "field2": "val2",
    "related_obj_field_1": "val1",
    "related_obj_field_2": "val2",

}

Currently I am achieving this using SerializerMethodField :目前我正在使用SerializerMethodField实现这一点:

class SomeSerializer(serializers.ModelSerializer):

    related_obj_field = serializers.SerializerMethodField()

    @staticmethod
    def get_related_obj_field(obj):
        return obj.related_obj.field

But I hope there's a cleaner way to do this.但我希望有一种更清洁的方法来做到这一点。

Well I don't guess there is some in-built Python functionality to flatten a dictionary, but you can write one by using the concept of recursion.好吧,我不认为有一些内置的 Python 功能可以使字典变平,但是您可以使用递归的概念编写一个。 The idea is to iterate over all the key, value pairs and see if the value is a dictionary, then call the recursive method, else just update the flatten dictionary with the key, value想法是遍历所有键值对并查看值是否是字典,然后调用递归方法,否则只需使用键值更新扁平字典

def flatten_dict(dictionary, flatten_dictionary):
    for k, v in dictionary.iteritems():
        if not isinstance(v, dict):
            flatten_dictionary[k] = v
        else:
            flatten_dict(v, flatten_dictionary)

f_dict = {}
flatten_dict(d, f_dict)
print f_dict
>>> {'field2': 'val2', 'related_obj_field_1': 'val1', 'related_obj_field_2': 'val2', 'field1': 'val1'}

Clear way for achieving it is using to_representation() method of Serializer.实现它的清晰方法是使用 Serializer 的to_representation()方法。 It helps modify serializer's data before converting to json:它有助于在转换为 json 之前修改序列化程序的数据:

class OrganizationUsersSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = UserOrganizations
        fields = ['organization_name', 'user']

    def to_representation(self, instance):
        data = super(OrganizationUsersSerializer, self).to_representation(instance)
        profile = data.pop('user')
        for key, val in profile.items():
            data.update({key: val})
        return data

So, you remove nested object and add its fields(specified in its own Serializer) to the same level.因此,您删除嵌套对象并将其字段(在其自己的序列化程序中指定)添加到同一级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM