这是我将文件上传到s3的代码。 现在我将其保存在本地
class UploadedImage(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(UploadedImage, self).save(force_update=force_update)
下面是我的序列化器
class UploadedImageSerializer(serializers.ModelSerializer):
class Meta:
model = UploadedImage
fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
read_only_fields = ('thumbnail',)
和观看次数
class UploadedImagesViewSet(viewsets.ModelViewSet):
queryset = UploadedImage.objects.all()
serializer_class = UploadedImageSerializer
这工作正常,但是在角度6中集成api时出现错误。
下面的角度为6 ts和html的代码
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { Router } from '@angular/router';
import { ViewChild } from '@angular/core';
@Component({
selector: 'app-photo-upload',
templateUrl: './photo-upload.component.html',
styleUrls: ['./photo-upload.component.css']
})
export class PhotoUploadComponent implements OnInit {
@ViewChild("fileInput") fileInput;
constructor(private http: HttpClient ,private router: Router) { }
ngOnInit() {
}
url: string | ArrayBuffer;
onSelectFile(event) { // called each time file input changes
if (event.target.files && event.target.files.length>0) {
console.log(event.target.files[0]);
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // read file as data url
reader.onload = () => { // called once readAsDataURL is completed
this.url = reader.result;
console.log(this.url);
}
}
}
photoupload(f){
this.onSelectFile(event)
f.value.images=this.url
console.log(f.value)
const header = new HttpHeaders({'Content-Type': 'application/json'});
this.http.post('http://11.111.11.111:8000/api/images/',
f.value,{headers:header}).subscribe(( data ) =>
{ console.log(data)
this.router.navigate(['../dashboard']);
}
,error => {console.log(error);
})
}
}
hmtl文件
<form (ngSubmit)="photoupload(list)" #list="ngForm" >
<div class="container">
<label for="title"><b>Photo Title</b></label>
<input type="text" name="title" placeholder="Enter Title" value="title" id="title" [(ngModel)]= "title" required >
<label for="discription"><b>Photo Description</b></label><br>
<input type="text" placeholder="Enter Description" name="discription" [(ngModel)]= "discription" required>
<label for="image"><b>Image </b></label>
<input type="file" name="image" (change)="onSelectFile($event)" required ><br>
<button type="submit">Upload Photo </button>
</div>
<div class="container" style="background-color:#f1f1f1">
</div>
</form>
现在我的问题是我的api在邮递员中工作,但我无法将其集成到angular 6上,这是与angular base 64 image有关的问题? 但是我也能够生成URL,我所能做的就是将这些数据从前端发送到后端
错误图片 problem image
答案 0 :(得分:0)
您正在使用Angular6前端调用API终结点时将Base64数据发送到后端。在这种情况下,您必须更新序列化程序并实现此类功能,以便它可以获取Base64数据并生成映像文件以保存在服务器上。
更新您的 UploadedImageSerializer ,如下所示
from rest_framework import serializers
class Base64ImageField(serializers.ImageField):
"""
A Django REST framework field for handling image-uploads through raw post data.
It uses base64 for encoding and decoding the contents of the file.
Heavily based on
https://github.com/tomchristie/django-rest-framework/pull/1268
Updated for Django REST framework 3.
"""
def to_internal_value(self, data):
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
self.fail('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
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 = UploadedImage
fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
read_only_fields = ('thumbnail',)
注意:此处的“缩略图”字段可能会引起问题。我将尽快更新此答案。
有关更多信息,请参阅Original Post