[Django]-Django REST Framework validate slug field

1👍

I think you would need to create a nested serializer for this to work. This is totally untested and off the top of my head, but maybe something like this:

class ActivityTagFieldSerializer(serializer.ModelSerializer):
    tag_name = serializers.SlugField()
    class Meta:
        model = Tag
        fields = ('tag_name')

class ActivitySerializer(serializer.ModelSerializer):
    activity_tags = ActivityTagFieldSerializer(many=True)
    class Meta:
        model = Activity
        fields = ('activity_tags', 'activity_project', ...)

    def create(self, validated_data):
        tags = validated_data.pop('activity_tags')
        activity = Activity.objects.create(**validated_data)
        for tag in tags:
            try:
                tag_to_add = Tag.objects.get(**tag)
            except:
                tag_to_add = Tag.objects.create(**tag)
            activity.activity_tags.add(tag_to_add)
        return activity

Check the API guide for writable nested serializers

1👍

I managed to do this by subclassing SlugRelatedField and overriding “to_internal_value” method. In the original implementation this method tries to get an object from the queryset, and if an object doesn’t exist it fails the validation. So instead of calling “get” method, I’m calling “get_or_create”:

class CustomSlugRelatedField(serializers.SlugRelatedField):
    def to_internal_value(self, data):
        try:
            obj, created = self.get_queryset().get_or_create(**{self.slug_field: data})
            return obj
        except (TypeError, ValueError):
            self.fail('invalid')

Leave a comment