python - Django Rest Framework Angulars upload file using ModelSerializer -


i'm trying upload image using django rest framework , angularjs i'm using ng-file-upload upload image angularjs.

i saw it's possible use apiviewset this. image in model , use modelserializer if it's possible prefer use modelviewset.

the problem when upload image got error:

image: ["the submitted data not file. check encoding type on form."] 

here 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 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) {             (var = 0; < 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 line

console.debug("files = ", $scope.files); 

prints in 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 

django's rest framework default way of dealing uploaded files examine header , decide how deal it:

http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser

by default ng-file-upload, uploads file in json format, means file uploading submitted base64 django, in turn try decode file using following:

http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser

this not work default django file field, there different ways accomplish this, 1 use following option (sendfieldas) in request:

upload.upload({     url: '/api/v1/images/',     ...     sendfieldsas: form, 

this submitt data form, django rest framework process should. other options, include decoding base64 , manually creating file used file field, adds overhead compared sendfieldas option.


Comments