dev-jim
dev-jim

Reputation: 2524

How to using django-taggit in DRF

I am having trouble to serialize the tags from django-taggit. I followed the instruction from here, but it is outdated.

Here is what I did:

views.py

class TagsSerializer(serializers.WritableField):

    def from_native(self, data):
        if type(data) is not list:
            raise ParseError("expected a list of data")
        return data

    def to_native(self, obj):
        if type(obj) is not list:
            return [tag.name for tag in obj.all()]
        return obj

I got this error :

'module' object has no attribute 'WritableField

Apparently the WritableField is deprecated.

I am using django 1.8, DRF 3.2 and django-taggit-0.17.

Upvotes: 1

Views: 2616

Answers (1)

Pieter Hamman
Pieter Hamman

Reputation: 1612

I would use the TaggableManager to update the tags, with a custom ListField to handle the serialisation of tags. Then you can use the serializer create/update methods to set the tags.

serializers.py

class TagSerializerField(serializers.ListField):
    child = serializers.CharField()

    def to_representation(self, data):
        return list(data.values_list('name', flat=True))

class TagSerializer(serializers.ModelSerializer):
    tags = TagSerializerField()

    def create(self, validated_data):
        tags = validated_data.pop('tags')
        instance = super(TagSerializer, self).create(validated_data)
        instance.tags.set(*tags)
        return instance

or you can use the perform_create/perform_update hooks in the view.

views.py

class TagView(APIView):
    queryset = Tag.objects.all()
    serializer_class = TagSerializer

    def perform_create(self, serializer):
        instance = serializer.save()
        if 'tags' in self.request.DATA:
            instance.tags.set(*self.request.DATA['tags'])

Upvotes: 7

Related Questions