Encoding the image to “base64”, send it to our DRF endpoint and on our DRF serializers change the ImageField to Base64ImageField was the implementation I used:
On the client side, on my angular app:
angular.controller('ImageUploadFormCtrl', function($scope, Photo){
$scope.submitForm = function(isValid){
if(isValid){
f = new FileReader(); // or $window.FileReader()
f.onload = function () {
$scope.formData.image = f.result; // This is a base64 string
Photo.save({}, $scope.formData).$promise.then(function(data){
// 200 Response
alert('Client image successfully updated.');
}, function(error){
// 400 Response
console.log('Error', error);
alert('An error has ocurred.');
})
};
// Read the file selected on the field with ID "image-field"
f.readAsDataURL(document.getElementById('image-field').files[0]);
}
}
});
On the server side on my Django app, specifically on the serializers.py file:
import base64, uuid
from django.core.files.base import ContentFile
class Base64ImageField(serializers.ImageField):
def to_internal_value(self, data):
if isinstance(data, basestring) and data.startswith('data:'): # You can change "data:" to "data/image:"
format, imgstr = data.split(';base64,')
ext = format.split('/')[-1]
id = uuid.uuid4()
data = ContentFile(base64.b64decode(imgstr), name=id.urn[9:])
return super(Base64ImageField, self).to_internal_value(data)
class PhotoSerializer(serializers.ModelSerializer):
image = Base64ImageField(allow_empty_file=False)
class Meta:
fields = ('id', 'image')
model = Photo
read_only_fields = ('id', )
I found out that this is the cleaner way to do this. If you have another alternative, please share it.
1 Comment
[…] http://xploit29.com/2016/09/13/upload-files-to-django-rest-framework-using-angularjs/ […]