Group serializer results based on value

不羁的心 提交于 2020-01-14 05:37:10

问题


I'm fairly new to Django, so I can't tell if this is possible using a class based view, but I would like to group search results based on a value in the JSON returned from the query. Basically I want my results to go from this:

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

To this:

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

Each "name/values" pair is a separate row in a MySQL database. My models.py looks like:

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) 

While the serializer looks like:

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

Any idea how I can do that? ListSerializer seems like it might be a likely candidate, and by extension so does adding many=True but I don't think that provides the grouping behavior I want. Any ideas?


回答1:


Use a regular Serializer - this is to say not a ModelSerializer - and override the view's methods to create your own structure and pass it to the serializer.




回答2:


You need to override the ListSerializer.to_representation. Read more about overriding .to_representation in the docs.

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


来源:https://stackoverflow.com/questions/37165051/group-serializer-results-based-on-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!