Is it possible to dynamically change field name in django-rest-framework serializer?

I have models Product

and ProductCategory

.

Let's say I have a ProductCategory TV

that has Sony

, Samsung

as its products. I also have a category MobilePhone

with Apple

and Nokia

as my products. Using DRF, I would like to receive JSON output using serializers that is similar to the one 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 the serializer must 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',
            }
    ]
}

      

from

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

      

But the names of dynamically changing fields are difficult to achieve. Is there a way to do this?

+3


source to share


1 answer


You can support this kind of custom format by overriding to_representation

your Serializer and the default ListSerializer
:



  • First, you overrideto_representation

    your serializer:

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

    So, your serialized categories are of the following form:

    {
        'Sony': {
          'price': '$100',
          'country': 'Japan'
        }
    }
    
          

  • Then, to add product_category

    before your list, you can use your own ListSerializer with a custom one 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
    
          

+3


source







All Articles