I'm trying to upload an image using Django Rest Framework and AngularJs I'm using ng-file-upload to upload the image with AngularJs.
I saw it's possible to use ApiViewSet to do this. But as my Image is in a model and I use ModelSerializer so if it's possible I prefer to use ModelViewSet.
The problem is when I upload the image I got an error:
image: ["The submitted data was not a file. Check the encoding type on the form."]
Here is my code
Models.py
class Image(models.Model):
image = models.ImageField(upload_to="articles")
article = models.ForeignKey(Article)
Serializers.py
class ImageSerializer(serializers.ModelSerializer):
class Meta:
#article = ArticleSerializer(read_only=True, required=False)
image = serializers.ImageField(use_url=True, allow_empty_file=True)
model = Image
fields = ('id', 'image', 'article')
read_only_fields = ('id', )
#def get_validation_exclusions(self, *args, **kwargs):
# exclusions = super(ImageSerializer, self).get_validation_exclusion()
# return exclusions + ['article']
Views.py
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.order_by('id')
serializer_class = ImageSerializer
class ImageArticleViewset(viewsets.ModelViewSet):
queryset = Image.objects.select_related('article').all()
serializer_class = ImageSerializer
def list(self, request, *args, image_pk=None):
queryset = self.queryset.filter(article__id=image_pk)
serializer = self.serializer_class(queryset, many=True)
return Response(serializer.data)
And the Controller
(function () {
'use strict';
angular
.module(nameProject + '.article.post.controller')
.controller('ArticlePostController', ArticlePostController);
ArticlePostController.$inject = ["$scope", "Articles", "Upload", "$timeout"];
function ArticlePostController($scope, Articles, Upload, $timeout) {
var vm = this;
vm.postArticle = postArticle;
$scope.$watch('files', function () {
$scope.upload($scope.files);
console.debug("files = ", $scope.files);
//console.debug("upload = ", $scope.upload);
});
$scope.upload = function (files) {
if (files && files.length) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.debug("file = ", file, "type = ", file.type);
Upload.upload({
url: '/api/v1/images/',
fields: {
'idArticle': 1,
'article': 1,
'image': file
},
file: file,
image:file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
$scope.log = 'progress: ' + progressPercentage + '% ' +
evt.config.file.name + '\n' + $scope.log
}).success(function (data, status, headers, config) {
$timeout(function () {
console.log("data === ", data.result);
$scope.log = 'file: ' + config.file.name + ', Response: ' + JSON.stringify(data) + '\n' + $scope.log;
});
});
}
}
};
}
})();
And this line
console.debug("files = ", $scope.files);
prints in the console
type = image/jpeg
The Jade template
form.form-signin(ng-submit="vm.postArticle()" enctype="multipart/form-data")
h2.form-signin-heading Post un article
input.input-block-level(type="text", name="title", placeholder="Title" ng-model="vm.title")
input.input-block-level(type="number", name="price", placeholder="Price" ng-model="vm.price")
input.input-block-level(type="text", name="content", placeholder="Description" ng-model="vm.description")
input.input-block-level(type="number", name="quantity", placeholder="Quantity" ng-model="vm.quantity")
input.input-block-level(type="text", name="color", placeholder="Color" ng-model="vm.color")
input.input-block-level(type="text", name="state", placeholder="State" ng-model="vm.state")
input.input-block-level(type="number", name="year", placeholder="Year" ng-model="vm.year")
p watching model
div(class="button" ngf-select ng-model="files" ngf-multiple="multiple") Select File on file change:
button.btn.btn-large.btn-primary(type="submit") Submit article