【发布时间】:2020-10-24 21:11:24
【问题描述】:
我有一个图像模型,Image,它在不同类型的文章上有外键。
我想通过 REST 接口(使用 Django-Rest-Framework 构建)公开这个模型,并通过 Angular 10 中的 AJAX 调用将图像上传到它。
到目前为止,在一般情况下进行文件上传工作,因为我能够成功关注this guide here(编辑:这是不正确的,因为我已经意识到。它确实创建了文件,但那些不是'不是实际的图像,它们实际上是不可读的)。
但它在某种程度上不适用于我的 ImageModel 和 ImageSerializer。当我此时触发我的 AJAX 调用时,目前我在前端收到 HTTP 500 响应,而在 Django 的后端收到此错误:
File "/home/isofruit/.virtualenvs/AldruneWiki-xa3nBChR/lib/python3.6/site-packages/rest_framework/serializers.py", line 207, in save
'create() did not return an object instance.'
这是我通过 AJAX 调用发送的 FormData 对象内容的控制台日志,但我的 Image 模型失败(控制台日志是通过迭代 FormData 获取的,因为仅记录 FormData 不会显示其内容)。请注意,除了图像之外,模型中不需要这些值:
在模型、序列化程序和 DRF 中的视图下方找到我的 Type-Script POST 方法以调用该 API:
//Typescript ImageUploadService.ts post method
postImage(imageModel: Image, imageFile: File){
const url = `${Constants.wikiApiUrl}/image/upload/`;
const formData: FormData = new FormData();
for ( var key in imageModel ) {
if (key==="image"){
formData.append("image", imageFile, imageFile.name);
} else if (imageModel[key]){
formData.append(key, imageModel[key]);
}
}
const options = {headers: new HttpHeaders({"Content-Disposition": `attachment; filename=${imageFile.name}`})}
return this.http.post(url, formData, options);
}
#serializers.py
class ImageSerializer (serializers.ModelSerializer):
image = serializers.ImageField("image.image")
class Meta:
model = wiki_models.Image
fields = [
'pk',
'image',
'name',
'character_article',
'creature_article',
'encounter_article',
'item_article',
'location_article',
'organization_article',
]
#api_views.py
class ImageUploadView(APIView):
parser_classes = (FileUploadParser,)
def post(self, request, *args, **kwargs):
image_serializer = ImageSerializer(data=request.data)
if image_serializer.is_valid():
image_serializer.save()
return Response(image_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(image_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# models.py
class Image(models.Model):
"""A table to hold additional images for articles"""
image = models.ImageField(upload_to='article_images',
default=settings.DEFAULT_IMAGE,
max_length=400)
name = models.CharField(max_length=400, null=True, blank=True, help_text='A name describing the image')
character_article = models.ForeignKey('Character', null=True, blank=True, related_name='character_gallery_image',
on_delete=models.CASCADE)
creature_article = models.ForeignKey('Creature', null=True, blank=True, related_name='creature_gallery_image',
on_delete=models.CASCADE)
encounter_article = models.ForeignKey('Encounter', null=True, blank=True, related_name='encounter_gallery_image',
on_delete=models.CASCADE)
item_article = models.ForeignKey('Item', null=True, blank=True, related_name='item_gallery_image',
on_delete=models.CASCADE)
location_article = models.ForeignKey('Location', null=True, blank=True, related_name='location_gallery_image',
on_delete=models.CASCADE)
organization_article = models.ForeignKey('Organization', null=True, blank=True, related_name='gallery_image',
on_delete=models.CASCADE)
class Meta:
ordering = ['creature_article', 'organization_article', 'location_article',
'encounter_article', 'item_article', 'character_article']
@property
def article(self):
fields = [field for field in self._meta.fields if 'article' in field.name and getattr(self, field.name) is not None]
if len(fields) > 1:
raise AssertionError(f'{self} is linked to more than one article!')
elif len(fields) < 1:
raise AssertionError(f'{self} is not linked to an article!')
else:
target_article_fieldname = fields[0].name
return getattr(self, target_article_fieldname)
@property
def article_fieldname(self):
article_model = type(self.article).__name__.lower()
return f'{article_model}_article'
编辑:
为了完整起见,并且因为需要这些信息来发现错误,这里是我使用的表单的 HTML 和 Typescript(我正在使用 Angular 的“Formly”生成表单):
<form [formGroup]="form" (ngSubmit)="cl(constants.createSignal)">
<formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
<div class="form-group">
<input type="file" (change)="onFileSelected($event)">
</div>
<button type="submit" class="btn btn-outline-secondary">Submit</button>
</form>
【问题讨论】:
标签: python django file django-models django-rest-framework