How can one customize Django Rest Framework serializers output?
Solution 1
Create a custom serializer field and implement to_native
so that it returns the list you want.
If you use the source="*"
technique then something like this might work:
class CustomField(Field):
def to_native(self, obj):
return obj.macAddresses.all()
I hope that helps.
Update for djangorestframework>=3.9.1
According to documentation, now you need override either one or both of the to_representation()
and to_internal_value()
methods. Example
class CustomField(Field):
def to_representation(self, value)
return {'id': value.id, 'name': value.name}
Solution 2
Carlton's answer will work do the job just fine. There's also a couple of other approaches you could take.
You can also use SlugRelatedField
, which represents the relationship, using a given field on the target.
So for example...
class WindowsCompleteMappingSerializer(serializers.Serializer):
id = serializers.Field()
macAddresses = serializers.SlugRelatedField(slug_field='address', many=True, read_only=True)
clientId = serializers.Field()
Alternatively, if the __str__
of the WindowsMacAddress
simply displays the address, then you could simply use RelatedField
, which is a basic read-only field that will give you a simple string representation of the relationship target.
# models.py
class WindowsMacAddress(models.Model):
address = models.TextField(unique=True)
mapping = models.ForeignKey('imaging.WindowsMapping', related_name='macAddresses')
def __str__(self):
return self.address
# serializers.py
class WindowsCompleteMappingSerializer(serializers.Serializer):
id = serializers.Field()
macAddresses = serializers.RelatedField(many=True)
clientId = serializers.Field()
Take a look through the documentation on serializer fields to get a better idea of the various ways you can represent relationships in your API.
ereOn
I love Golang, networking and security. If you need an open-source, free, multi-platform, VPN solution, you may want to check http://www.freelan.org which is basically how I spend my free time.
Updated on July 23, 2022Comments
-
ereOn almost 2 years
I have a Django model that is like this:
class WindowsMacAddress(models.Model): address = models.TextField(unique=True) mapping = models.ForeignKey('imaging.WindowsMapping', related_name='macAddresses')
And two serializers, defined as:
class WindowsFlatMacAddressSerializer(serializers.Serializer): address = serializers.Field() class WindowsCompleteMappingSerializer(serializers.Serializer): id = serializers.Field() macAddresses = WindowsFlatMacAddressSerializer(many=True) clientId = serializers.Field()
When accessing the serializer over a view, I get the following output:
[ { "id": 1, "macAddresses": [ { "address": "aa:aa:aa:aa:aa:aa" }, { "address": "bb:bb:bb:bb:bb:bb" } ], "clientId": null } ]
Almost good, except that I'd prefer to have:
[ { "id": 1, "macAddresses": [ "aa:aa:aa:aa:aa:aa", "bb:bb:bb:bb:bb:bb" ], "clientId": null } ]
How can I achieve that ?
-
Hieu Nguyen over 10 yearsHmm I thought
RelatedField
andSlugRelatedField
only work withModelSerializer
? -
Tom Christie over 10 yearsAll the relational fields work with Django model relationships. They'll work just fine either used on a
Serializer
or aModelSerializer
class. -
Hieu Nguyen over 10 yearsThanks! It will be useful for me later on.
-
vimal1083 almost 8 yearsAll the links given are broken, could you please update it