djangodjango-modelsdjango-rest-frameworkdjango-serializermanytomanyfield

Getting serialized data in another format


How can I get JSON in a new format such as text/value like:

[
    {
        "name": "doc2",
        "directions": [
       
            "mar", 
            "qwe"
           
        ]
    },
    {
        "name": "John",
        "directions": [
              "Surgery",
              "qwe"
        ]
    }
]

instead of:

[
    {
        "name": "doc2",
        "directions": [
            {
                "name": "mar"
            },
            {
                "name": "qwe"
            }
        ]
    },
    {
        "name": "John",
        "directions": [
            {
                "name": "Surgery"
            },
            {
                "name": "qwe"
            }
        ]
    }
]

Here are my models.py and serializers.py modules: models.py

class Directions(models.Model):
    name = models.CharField(max_length=355)

    def __str__(self):
        return self.name


class Doctors(models.Model):
    name = models.CharField(max_length=255)
    directions = models.ManyToManyField(Directions)

    def __str__(self):
        return self.name

serializer.py

class DirectionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Directions
        fields = ('name',)


class DoctorsSerializer(serializers.ModelSerializer):
    directions = DirectionsSerializer(many=True)
    class Meta:
        model = Doctors
        fields = ('name', 'directions')

Solution

  • You have two options for achieving this purpose:

    1. Using Custom relational fields [drf-docs]

    For your case, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration:

    
    class DirectionsSerializer(serializers.RelatedField):
        def to_representation(self, value):
            return value.name
    
    class DoctorsSerializer(serializers.ModelSerializer):
        directions = DirectionsSerializer(many=True)
    
        class Meta:
            model = Doctors
            fields = ['name', 'directions']
    

    This custom field would then serialize to the following representation:

    [
        {
            "name": "doc2",
            "directions": [
           
                "mar", 
                "qwe"
               
            ]
        },
        {
            "name": "John",
            "directions": [
                  "Surgery",
                  "qwe"
            ]
        }
    ]
    

    2. Using StringRelatedField() [drf-docs]

    StringRelatedField may be used to represent the target of the relationship using its __str__ method.

    For your case, the following serializer:

    class DoctorsSerializer(serializers.ModelSerializer):
        directions = serializers.StringRelatedField(many=True)
    
        class Meta:
            model = Doctors
            fields = ['name', 'directions']
    

    Would serialize to the following representation:

    [
        {
            "name": "doc2",
            "directions": [
           
                "mar", 
                "qwe"
               
            ]
        },
        {
            "name": "John",
            "directions": [
                  "Surgery",
                  "qwe"
            ]
        }
    ]
    

    This field is read_only.

    Arguments: