Handling images as base64 strings with Django REST Framework

Published by at 4th July 2015 12:01 pm

I'm currently working on a Phonegap app that involves taking pictures and uploading them via a REST API. I've done this before, and I found at that time that the best way to do so was to fetch the image as a base-64 encoded string and push that up, rather than the image file itself. However, the last time I did so, I was using Tastypie to build the API, and I've since switched over to Django REST Framework as my API toolkit of choice.

It didn't take long to find this gist giving details of how to do so, but it didn't work as is, partly because I was using Python 3, and partly because the from_native method has gone as at Django REST Framework 3.0. It was, however, straightforward to adapt it to work. Here's my solution:

1import base64, uuid
2from django.core.files.base import ContentFile
3from rest_framework import serializers
4
5
6# Custom image field - handles base 64 encoded images
7class Base64ImageField(serializers.ImageField):
8 def to_internal_value(self, data):
9 if isinstance(data, str) and data.startswith('data:image'):
10 # base64 encoded image - decode
11 format, imgstr = data.split(';base64,') # format ~= data:image/X,
12 ext = format.split('/')[-1] # guess file extension
13 id = uuid.uuid4()
14 data = ContentFile(base64.b64decode(imgstr), name = id.urn[9:] + '.' + ext)
15 return super(Base64ImageField, self).to_internal_value(data)

This solution will handle both base 64 encoded strings and image files. Then, just use this field as normal.