我试图通过django rest API将图像从Ionic 2应用上载到Django驱动的网站。
API正在通过Postman进行工作和测试,但我总是会在离子化中获得HTTP 400不良请求错误。
这是我在离子中的代码:
openCamera(){
var options = {
sourceType: Camera.PictureSourceType.CAMERA,
destinationType: Camera.DestinationType.DATA_URL
};
Camera.getPicture(options).then((imageData) => {
this.imageName = imageData;
this.imageURL = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
this.showAlert(err);
});
}
上传文件(我在我的本地PC上使用IP地址192.168.22.4为我的Django项目提供服务:
transferData(auth){
let headers = new Headers();
headers.append('Authorization', auth);
let formData = new FormData();
formData.append('image', this.imageURL, this.imageName);
this.http.post("http://192.168.22.4/api-imageUpload", formData, {headers: headers}).subscribe(res => {
let status = res['status'];
if(status == 200){
this.showAlert( "The image was successfully uploaded!");
}else{
this.showAlert("upload error");
}
}, (err) => {
var message = "Error in uploading file " + err
this.showAlert(message);
});
}
在django上,这是我的序列化器:
class ImageDetailsSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None, use_url=True)
class Meta:
model = ImageDetails
fields= ('image','status','category', 'user') ####status, category has default value
和Views.py:
class ImageDetailsViewSet(generics.ListCreateAPIView):
queryset = ImageDetails.objects.all()
serializer_class = ImageDetailsSerializer
我不确定上传文件中的代码是否正确。由于表单在我的API中效果很好,因此我正在尝试通过表单数据传递数据。这个方法正确吗?还有其他方法可以完成这项工作吗?
注意:我尝试使用转移Cordova插件,但它不起作用。
我最终解决了问题。HTTP 400表示代码中某处存在语法错误,这是上传照片中使用的编码。移动数据使用基本64编码。发送请求时,该文件将转换为Unicode字符串。
另一方面,django-rest使用图像的普通编码,因此默认情况下,它不能支持base64图像。但幸运的是,该插件已经可以在GitHub上找到。
您只需要安装插件并将其导入在serializers.py上:
from drf_extra_fields.fields import Base64ImageField
class ImageDetailsSerializer(serializers.ModelSerializer):
image = Base64ImageField()
class Meta:
model = ImageDetails
fields= ('image','status','category', 'user')
在离子方面,您必须提交实际图像而不是imageUrl。就我而言,我只需要调整我的代码:
transferData(auth){
let headers = new Headers();
headers.append('Authorization', auth);
let formData = new FormData();
formData.append('category', 1);
formData.append('status', 'Y')
formData.append('image', this.imageName);
this.http.post("http://192.168.22.4/api-imageUpload", formData, {headers: headers}).subscribe(res => {
let status = res['status'];
if(status == 201){
var message = "The image was successfully uploaded!";
this.showAlert(message);
}else{
var message = "upload error";
this.showAlert(message);
}
}, (err) => {
var message = "Error in uploading file " + err;
this.showAlert(message);
});
为了检查请求的持续情况:
from rest_framework.exceptions import ValidationError
class ImageDetailsViewSet(generics.ListCreateAPIView):
queryset = ImageDetails.objects.all()
serializer_class = ImageDetailsSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
print(serializer.errors) # or better use logging if it's configured
raise ValidationError(serialize.errors)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
即使没有base64,也可以使用file-transfer的离子本机组件和图像派克,请参见:https://gist.github.com/andreasdickow/9d5fcd5fcd2c608b4726d16d16dda37cc8888888888888888888888888880ab
<<