Django Rest Framework Angulars 使用 ModelSerializer 上传文件
Django Rest Framework Angulars upload file using ModelSerializer
我正在尝试使用 Django Rest Framework 和 AngularJs 上传图像
我正在使用 ng-file-upload 上传带有 AngularJs.
的图像
我看到可以使用 ApiViewSet 来执行此操作。但是由于我的图像在模型中并且我使用 ModelSerializer 所以如果可能的话我更喜欢使用 ModelViewSet。
问题是当我上传图片时出现错误:
image: ["The submitted data was not a file. Check the encoding type on the form."]
这是我的代码
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)
和控制器
(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;
});
});
}
}
};
}
})();
还有这一行
console.debug("files = ", $scope.files);
在控制台打印
type = image/jpeg
Jade 模板
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 的 REST Framework 默认处理上传文件的方式是检查文件头并决定如何处理它:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
默认情况下,ng-file-upload 以 json
格式上传文件,这意味着您上传的文件作为 Base64 提交给 Django,Django 将尝试使用以下:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
这不适用于默认的 Django 文件字段,有多种方法可以完成此操作,一种是在您的请求中使用以下选项 (sendFieldAs
):
Upload.upload({
url: '/api/v1/images/',
...
sendFieldsAs: form,
这将以表单形式提交数据,Django REST 框架将对其进行处理。其他选项包括解码 Base64 和手动创建要与文件字段一起使用的文件,与 sendFieldAs
选项相比会增加开销。
我正在尝试使用 Django Rest Framework 和 AngularJs 上传图像 我正在使用 ng-file-upload 上传带有 AngularJs.
的图像我看到可以使用 ApiViewSet 来执行此操作。但是由于我的图像在模型中并且我使用 ModelSerializer 所以如果可能的话我更喜欢使用 ModelViewSet。
问题是当我上传图片时出现错误:
image: ["The submitted data was not a file. Check the encoding type on the form."]
这是我的代码
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)
和控制器
(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;
});
});
}
}
};
}
})();
还有这一行
console.debug("files = ", $scope.files);
在控制台打印
type = image/jpeg
Jade 模板
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 的 REST Framework 默认处理上传文件的方式是检查文件头并决定如何处理它:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
默认情况下,ng-file-upload 以 json
格式上传文件,这意味着您上传的文件作为 Base64 提交给 Django,Django 将尝试使用以下:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
这不适用于默认的 Django 文件字段,有多种方法可以完成此操作,一种是在您的请求中使用以下选项 (sendFieldAs
):
Upload.upload({
url: '/api/v1/images/',
...
sendFieldsAs: form,
这将以表单形式提交数据,Django REST 框架将对其进行处理。其他选项包括解码 Base64 和手动创建要与文件字段一起使用的文件,与 sendFieldAs
选项相比会增加开销。