组序列化程序基于值的结果

时间:2016-05-11 14:03:52

标签: python django django-rest-framework django-class-based-views

我是Django的新手,所以我无法判断使用基于类的视图是否可行,但我想根据查询返回的JSON中的值对搜索结果进行分组。基本上我希望我的结果是这样的:

{
"id": "0038",
"attributes": [
    {
        "name": "State",
        "values": "CA"
    },
    {
        "name": "Areas",
        "values": "Value 1"
    },
    {
        "name": "Areas",
        "values": "Value 2"
    },
    {
        "name": "Areas",
        "values": "Value 3"
    }]}

对此:

{"id": "0038",
"attributes": [
    {
        "name": "State Licenses",
        "values": "CA"
    },
    {
        "name": "Areas",
        "values": ["Value 1", "Value 2", "Value 3"]
    }]}

每个“名称/值”对是MySQL数据库中的单独行。我的models.py看起来像:

class Attribute(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=45, blank=False)
    value = models.CharField(max_length=255, blank=False) 

虽然序列化器看起来像:

class AttributeSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='name')
    values = serializers.CharField(source='value')
    class Meta:
        model = models.Attribute
        fields= ('name','values')

知道我该怎么做吗? ListSerializer似乎可能是一个可能的候选者,并且通过扩展,添加many=True也是如此,但我不认为这提供了我想要的分组行为。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

使用常规Serializer - 也就是说不是ModelSerializer - 并覆盖view's methods以创建自己的结构并将其传递给序列化程序。

答案 1 :(得分:0)

您需要覆盖ListSerializer.to_representation。详细了解docs中覆盖.to_representation的内容。

def transform_data(data):
    result = {}
    for item in data:
        name, value = item['name'], item['value']
        if result.get(name):
            result[name].append(value) 
        else:
            result[name] = [value]
    return result


class AttributeListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        data = super(AttributeListSerializer, self).to_representation(data)
        # data is currently in this format:
        # [
        #     {"name": "State", "values": "CA"},
        #     {"name": "Areas", "values": "1"},
        # ]
        # transform_data can be updated to transform the data however you like...
        return transform_data(data)


class AttributeSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='name')
    values = serializers.CharField(source='value')
    class Meta:
        model = models.Attribute
        fields= ('name','values')
        # the below is KEY
        list_serializer_class = AttributeListSerializer