The DRF docs describe a way to create nested serializers that can produce dicts like this:
{
"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
:
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. 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. It helps modify serializer's data before converting to 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.