2013-05-28 101 views
2

使用Django & Django的REST的架構,我有以下的模型(這是簡化的,但是這一切都沒有):序列化作爲dictionnary對象的列表中DjangoRestFramework

class Device(Model): 
    #stuff 

class DeviceInformation(Model): 
    device = ForeignKey(Device, reverse='infos') 
    key = CharField(max_length=32) 
    value = CharField(max_length=1024) 

當序列通過django-設備rest-framework的ModelSerializer,我得到這樣的東西:

{ 
    //stuff 
    infos: [{ 
     'key':'BatteryLevel', 
     'value':'80%' 
    },{ 
     'key':'DeviceName', 
     'value':'my device' 
    }, //etc 
    ] 
} 

這是完全正常的。然而,將它序列化成這樣的東西會更有意義:

{ 
    //stuff 
    infos: { 
     'BatteryLevel':'80%', 
     'DeviceName':'my device', 
     //etc 
    } 
} 

我該怎麼做?它甚至有可能嗎? 請注意,我不需要反序列化任何這些信息。

編輯:我的串行如下:

class DeviceInfoSerializer(ModelSerializer): 
    class Meta: 
     model = DeviceInformation 
     fields = ('key', 'value') 
     read_only_fields = fields 


class DeviceSerializer(HyperlinkedModelSerializer): 

    udid = serializers.CharField(read_only=True) 

    def __init__(self, *args, **kwargs): 
     super(DeviceSerializer, self).__init__(*args, **kwargs) 
     if hasattr(self, 'object') and self.object and not self.many: 
      self.data['infos'] = DeviceInfoSerializer(
       self.object.infos.all(), many=True).data 

    class Meta: 
     model = Device 
     fields = ['udid', 'model', 'tracked'] 
     read_only_fields = ('model', 'tracked') 
     slug_field = 'udid' 
+0

不是專家,如果重寫'get_field(..)'或'get_key_field()'和'get_value_field()'會怎麼樣。看到這裏http://django-rest-framework.org/api-guide/serializers.html#customising-the-default-fields – EsseTi

+0

檢查源後,這將無法正常工作。但是,通過自定義'Field'並覆蓋'to_native(...)'應該可以實現這一點。然而,我覺得這非常黑客。 – Habfast

+0

你的序列化程序是什麼樣的? – Jeff

回答

0

爲了您只讀的情況下,最好的辦法是使用SerializerMethodField

這會改變您的DeviceSerializer並刪除您的需要DeviceInfoSerializer

class DeviceSerializer(HyperlinkedModelSerializer): 
    udid = serializers.CharField(read_only=True) 
    infos = serializers.SerializerMethodField('get_infos') 

    def get_infos(self, obj): 
     return { 
      info.key: info.value 
      for info in obj.infos.all() 
     } 

    class Meta: 
     model = Device 
     fields = ['udid', 'model', 'tracked', 'infos'] 
     read_only_fields = ('model', 'tracked', 'infos') 
     slug_field = 'udid'