is it possible to dynamically change field name within django-rest-framework serializer?

筅森魡賤 提交于 2020-02-27 08:55:12

问题


I have Product and ProductCategory models.

Let's say I have ProductCategory TV, which has Sony, Samsung as its products. I also have MobilePhone category with Apple and Nokia as its products. Using DRF, I would like to get JSON output using serializers, which is similar to the below:

{
    'TV': 
        [
            'Sony': 
                {
                    'price': '$100',
                    'country': 'Japan',
                },
            'Samsung': 
                {
                    'price': '$110',
                    'country': 'Korea',
                }
        ]

    'mobile_phone':
        [
            'Apple': 
                {
                    'price': '$300',
                    'country': 'USA',
                },
            'Nokia': 
                {
                    'price': '$210',
                    'country': 'Finland',
                }
        ]
}

The problem here is that the field names('TV', 'mobile_phone') in serializer have to be dynamic.

I know I can get the following JSON type

{ 
    [
            {   
                'product_category': 'TV',
                'manufacturer: 'Sony',
                'price': '$100',
                'country': 'Japan',
            },
            {
                'product_category': 'TV',
                'manufacturer: 'Samgsung',
                'price': '$110',
                'country': 'Korea',
            }
    ]

    [
            {
                'product_category': 'mobile_phone',
                'manufacturer: 'Samgsung',
                'price': '$300',
                'country': 'USA',
            },
            {
                'product_category': 'mobile_phone',
                'manufacturer: 'Apple',
                'price': '$210',
                'country': 'Finland',
            }
    ]
}

with

class CategorySerializer(serializers.Serializer):
    product_category = serializer.CharField()
    manufacturer = serializer.CharField()
    price = serializer.CharField()
    country = serializer.CharField()

But the dynamically-changing-field-names is difficult to achieve. Is there any way I can do this?


回答1:


You can support this kind of custom format by overriding to_representation of your Serializer and of the default ListSerializer:

  1. First, you override to_representation of your serializer:

    class CategorySerializer(serializers.Serializer):
        # your fields here
    
        def to_representation(self, obj):
          return {
              obj.manufacturer: {
                 'price': obj.price,
                 'country': obj.country
              }
          }
    

    So that your serialized categories are of this form:

    {
        'Sony': {
          'price': '$100',
          'country': 'Japan'
        }
    }
    
  2. Then to prepend the product_category in front of your list, you can use a custom ListSerializer with a custom to_representation:

    class CategoryListSerializer(serializers.ListSerializer):
    
        def to_representation(self, data):
            # Group your data entries by category here
            ...
            return {
                'TV': tv_data
                'mobile_phone': mobile_data
            }
    
    class CategorySerializer(serializers.Serializer):
        ...
        class Meta:
          list_serializer_class = CategoryListSerializer
    


来源:https://stackoverflow.com/questions/43157028/is-it-possible-to-dynamically-change-field-name-within-django-rest-framework-ser

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