Django上传错误:上传有效图片

时间:2017-03-12 18:05:49

标签: angularjs django

我正在寻找通过角度和django休息来发布图像的最简单方法。

我已经采用了一些代码示例并将其合并到此,但我仍然收到错误:

  

上传有效图片。您上传的文件不是图像或损坏的图像。

也许有人有良好的眼光,很容易看到我在这里缺少的东西?

P.S。 libjpeg-dev已经是最新版本了

javascript.js

/* global angular */
var products = angular.module('products',['ngCookies']);

products.config(function($interpolateProvider) {
    //allow django templates and angular to co-exist
    $interpolateProvider.startSymbol('{[{');
    $interpolateProvider.endSymbol('}]}');
});

products.run(function($rootScope, $log, $http, $cookies) {

    $http.defaults.headers.common['X-CSRFToken'] = $cookies['csrftoken'];

});

products.factory('ModelUtils', function($http, $log) {


    var handleErrors =  function(serverResponse, status, errorDestination) {
            if (angular.isDefined(errorDestination)) {
                if (status >= 500) {
                    errorDestination.form = 'Server Error: ' + status;
                } else if (status >= 401) {
                    errorDestination.form = 'Unauthorized Error: ' + status;
                } else {
                    angular.forEach(serverResponse, function(value, key) {
                        if (key != '__all__') {
                            errorDestination[key] = angular.isArray(value) ? value.join("<br/>") : value;
                        } else {
                            errorDestination.form = errorDestination.form || '' + key + ':' + angular.isArray(value) ? value.join("<br/>") : value;
                        }
                    });
                }
            }
        };

    var ModelUtils = {
        get: function(url,id) {
            $http.get(url + id + '/').then(function(response){response.data});
        },
        create: function(url, obj, errors) {

            //TODO
            //obj.author = username;
            return $http.post(url, obj).
                success(function(response, status, headers, config) {
                    angular.extend(obj, response);
                }).
                error(function(response, status, headers, config) {
                    handleErrors(response, status, errors);
                });
        },
        save: function(url, obj, errors) {
            if (angular.isDefined(obj.id)) {
                return $http.put(url + obj.id + '/', obj).
                        success(function(response, status, headers, config) {
                            angular.extend(obj, response);
                        });
                        error(function(response, status, headers, config) {
                            handleErrors(response, status, errors);
                        });
            } else {
                return this.create(url, obj, errors);
            }
        },
        del: function(url, obj) {
            console.log(url, obj, obj.id);
            return $http.delete(url + obj.id + '/');
        }
    };
    return ModelUtils;
});

products.controller('ListCtrl', function ListCtrl($scope, $log, $http, ModelUtils) {

    // dcl variables
    $scope.tempUrlJs = document.getElementById("tempVar1").value;

    // just a dummy init function
    $scope.initialize = function(data) {
        $log.log('initialize',data);
        $scope.initData = data;
    };

    $scope.loaditems = function() {
      console.log('hello');
        $scope.items = $http.get('/api/images/').then(function(response){
            return response.data;
        });
    };

    //mainFlow
    $scope.loaditems($scope.tempUrlJs);
    $scope.currentitem = {};
    $scope.errors = {};
    console.log('hello');

    $scope.saveitem = function() {
        console.log('hello');
        ModelUtils.save('/api/images/',$scope.currentitem, $scope.errors).then(function(){
            $scope.loaditems();
            $scope.currentitem = {};
        });
    };
    $scope.delitem = function(item) {
        console.log('0');
        ModelUtils.del('/api/images/',item).then(function(){
            console.log('10');
            $scope.loaditems();
        });
    };
});
products.controller('subListCtrl', function ListCtrl($scope, $log, $http, ModelUtils) {
  // dcl variables
  $scope.tempUrlJs = '/api/ingredients/'
  //document.getElementById("tempVar2").value;

  // just a dummy init function
  $scope.initialize = function(data) {
      $log.log('initialize',data);
      $scope.initData = data;
  };

  $scope.loaditems = function(tempUrlJs) {
      $scope.items = $http.get(tempUrlJs).then(function(response){
          return response.data;
      });
  };

  $scope.saveitem = function() {
      ModelUtils.save('/api/ingredients/',$scope.currentitem, $scope.errors).then(function(){
          $scope.loaditems();
          $scope.currentitem = {};
      });
  };

  //mainFlow
  $scope.loaditems($scope.tempUrlJs);
  $scope.currentitem = {};
  $scope.errors = {};

});

index.html

    <body ng-app="products">
      <div ng-controller="ListCtrl">
        <h3>Insert image</h3>
        <form>
            <ul>
                <li>Title: <input type="text" name="title" ng-model="currentitem.title"/><span class="error">{[{ errors.title }]}</span></li>
                <li>Description:  <input type="text" name="description" ng-model="currentitem.description"/><span class="error">{[{ errors.description }]}</span></li>
                <li>Image: <input type="file" name="image" ngf-select ng-model ="currentitem.image" accept="image/*"/><span class="error">{[{ errors.image }]}</span></li>
            </ul>
            <button ng-click="saveitem()">Save</button>
            <pre>currentitem:{[{ currentitem | json }]}</pre>
        </form>

serializers.py

    class Base64ImageField(serializers.ImageField):

        def to_internal_value(self, data):
            from django.core.files.base import ContentFile
            import base64
            import six
            import uuid

            def decode_base64(data):

                missing_padding = len(data) % 4
                if missing_padding != 0:
                    data += b'='* (4 - missing_padding)
                return base64.decodestring(data)

            if isinstance(data, six.string_types):
                if 'data:' in data and ';base64,' in data:
                    header, data = data.split(';base64,')
                try:
                    data = decode_base64(data)
                    decoded_file = base64.b64decode(data)
                    #decoded_file = decode_base64(decoded_file)
                except TypeError:
                    self.fail('invalid_image')

                file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough
                file_extension = self.get_file_extension(file_name, decoded_file)
                complete_file_name = "%s.%s" % (file_name, file_extension, )
                data = ContentFile(decoded_file, name=complete_file_name)

            return super(Base64ImageField, self).to_internal_value(data)

        def get_file_extension(self, file_name, decoded_file):
            import imghdr

            extension = imghdr.what(file_name, decoded_file)
            extension = "jpg" if extension == "jpeg" else extension

            return extension

    class UploadedImageSerializer(serializers.ModelSerializer):

            image = Base64ImageField(
                max_length=None, use_url=True,
            )

            class Meta:
                model = image
                fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
                read_only_fields = ('thumbnail',)

views.py

    class UploadedImages(TemplateView):

        template_name = 'image.html'

        queryset = image.objects.all()
        serializer_class = UploadedImageSerializer

    class UploadedImagesApi(generics.ListCreateAPIView):

        queryset = image.objects.all()
        model = image
        serializer_class = UploadedImageSerializer

models.py

    def scramble_uploaded_filename(instance, filename):
        extension = filename.split(".")[-1]
        return "{}.{}".format(uuid.uuid4(), extension)


    def create_thumbnail(input_image, thumbnail_size=(256, 256)):
        if not input_image or input_image == "":
            return

        image = Image.open(input_image)
        image.thumbnail(thumbnail_size, Image.ANTIALIAS)
        filename = scramble_uploaded_filename(None, os.path.basename(input_image.name))
        arrdata = filename.split(".")
        extension = arrdata.pop()
        basename = "".join(arrdata)
        new_filename = basename + "_thumb." + extension
        image.save(os.path.join(settings.MEDIA_ROOT, new_filename))

        return new_filename


    class image(models.Model):
        image = models.ImageField("Uploaded image", upload_to=scramble_uploaded_filename)
        thumbnail = models.ImageField("Thumbnail of uploaded image", blank=True)
        title = models.CharField("Title of the uploaded image", max_length=255, default="Unknown Picture")
        description = models.TextField("Description of the uploaded image", default="")

        def __str__(self):
            return self.title

        def save(self, force_insert=False, force_update=False, using=None, update_fields=None):

            self.thumbnail = create_thumbnail(self.image)
            super(image, self).save(force_update=force_update)

1 个答案:

答案 0 :(得分:0)

我不知道有角度,所以这可能是完全错误的,但您是否总是需要foo[0, 42, 42, 7] = 0.72代码中的enctype="multipart/form-data"来上传图片?