我正在为应用创建Django api server
。
该应用程序的概念是一张照片日记,用户可以上传带有许多照片的日记(一个帖子)。(ForeignKey相关)
api服务器处理图像文件,所以我使用VersatileImageField
,django第三方模块,用于图像域。
客户端可以请求许多图像文件,因此我想使用Celery
进行图像处理。对于Celery工作者,我传递了django.core.files.uploadedfile.InMemoryUploadedFile
(文件)和模型实例的ID。
但是当我通过File
时,会出现错误
UnicodeDecodeError: 'utf-8' codec can't decode
byte 0xff in position 0: invalid start byte
所以我的新策略是
1.使用python base64
模块并对图像文件进行编码并将File
包裹起来
2.将图像File
发送给芹菜工人
3.任务解码File
并使用它创建一个Image实例。
以下是用于将File
传递给任务的序列化程序创建方法。
def create(self, validated_data):
photos_data = list(validated_data.pop('photo_set'))
for photo in photos_data:
# photos_data is the list of `InMemoryUploadedFile`
# Encoding image file
encoded_photo = base64.b64encode(photo.read())
photo.seek(0)
photo.truncate()
photo.write(encoded_photo)
photo.seek(0)
post = Post.objects.create(
**validated_data,
)
# celery task
task_upload_photos.delay(photos_data=photos_data, post_id=post.id)
return post
任务就像这样
@shared_task
def task_upload_photos(photos_data, post_id):
post = Post.objects.get(id=post_id)
if photos_data:
for photo in photos_data:
decoded_photo = base64.b64decode(photo.read())
photo.seek(0)
photo.truncate()
photo.write(decoded_photo)
photo.seek(0)
Photo.objects.create(post=post, photo=photo)
photo.close()
return {'Message': 'Photos are created.'}
else:
return {'Message': 'No photos delivered.'}
是的,我觉得它并不那么酷。我搜索了其他帖子,很多人说
only send instances' id, not instances' themselves
。
但我认为这个解决方案可以很好地解决问题。但是,当我制作照片并尝试检索它们时,会引发另一个例外。
OSError at /posts/post_list/111/ cannot identify image file
<File: `path`/media/photo/photo/asdf_0sbMULC.jpg>
它说它无法识别解码图像File
和
我真的想知道为什么会出错。
我在发送之前以及编码和解码之后打印出type
和len
个图像文件,并且它们相同。
我错过了什么吗?请给我一些建议 为何出现操作系统错误,无法将其作为图像文件读取 谢谢