0

I have two models created in my Django app and am looking for a serialization approach so that the IPs are shown in JSON as a list of strings instead of a list of IPAddress objects.

Desired JSON

[
    {
        "hostname": "www.example.com",
        "ip_addresses": [ "1.1.1.1", "2.2.2.2" ]
    }
] 

Current JSON

[
    {
        "hostname": "www.example.com",
        "ip_addresses": [
            {
                "id": 1,
                "ip_address": "1.1.1.1"
            },
            {
                "id": 2,
                "ip_address": "2.2.2.2"
            }
        ]
] 

urls.py

class HostSerializer(serializers.ModelSerializer):
    hostname = serializers.CharField(source='name', read_only=True)

    class Meta:
        model = Host
        fields = ['hostname', 'ip_addresses']
        depth = 1

models.py

class IPAddress(models.Model):
    ip_address = models.GenericIPAddressField()

    def __str__(self):
        return str(self.ip_address)

class Host(models.Model):
    name = models.CharField(max_length=100)
    ip_addresses = models.ManyToManyField(IPAddress)

    def __str__(self):
        return self.name

2 Answers 2

1

Try out this !

class HostSerializer(serializers.Serializer):
    hostname = serializers.CharField(source='name', read_only=True)
    ip_addresses = serializers.SerializerMethodField(read_only=True)

    def get_ip_addresses(self, instance):
        return [item.ip_address for item in instance.ip_addresses.all()]
Sign up to request clarification or add additional context in comments.

1 Comment

You don't need to add read_only=True to SerializerMethodField since it is already read-only.
0

You can use serializers.SerializerMethodField() to achieve what you want:

class HostSerializer(serializers.ModelSerializer):
    hostname = serializers.CharField(source='name', read_only=True)
    ip_addresses: serializers.SerializerMethodField()

    class Meta:
        model = Host
        fields = ['hostname', 'ip_addresses']
        depth = 1

    def get_ip_addresses(self, instance):
        return [item.ip_address for item in instance.ip_addresses]

2 Comments

Hmm still getting the same JSON response
@kernelpanic Looks like I forgot to add all() to get instance.ip_addresses :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.