Search code examples
pythonserializationdjango-rest-framework

DRF serialize ArrayField as string


I have a Model with an ArrayField tags and I need it to serialize back and forth as a string of values separated by comma.

models.py

from django.contrib.postgres.fields import ArrayField

class Snippet(models.Model):
    tags = ArrayField(models.CharField(max_length=255), default=list)

I want this field to be handled as a string of tags like tag1,tag2,tag3, I can handle this in the model save() method but DRF is complaining with {tags: ["Expected a list of items but got type "str"."]}.

serializers.py

class SnippetSerializer(serializers.ModelSerializer):

class Meta:
    model = Snippet
        fields = ('tags')

What can I do in DRF to manage this field as a string ? I am using React in the front-end and I could handle it there but I prefer handling this in the backend rather than the client-side.


Solution

  • You need to create a custom field that handles the format that you want The rest framework mapping field of postgres ArrayField is a ListField, so you can subclass that.

    from rest_framework.fields import ListField
    
    class StringArrayField(ListField):
        """
        String representation of an array field.
        """
        def to_representation(self, obj):
            obj = super().to_representation(self, obj)
            # convert list to string
           return ",".join([str(element) for element in obj])
    
        def to_internal_value(self, data):
            data = data.split(",")  # convert string to list
            return super().to_internal_value(data)
    

    Your serializer will become:

    class SnippetSerializer(serializers.ModelSerializer):
        tags = StringArrayField()
    
        class Meta:
            model = Snippet
            fields = ('tags')
    

    More info about writing rest framekwork custom fields here: http://www.django-rest-framework.org/api-guide/fields/#examples