无法在 Django Admin 中将 InMemoryUploadedFile 保存到 S3
我正在使用 django-storage 包,并尝试一次上传多个图像。因此,我覆盖了 ModelAdmin 中的 add_view 和 save_model 方法,以便删除原始图像字段并使用模板 HTML 中给出的自定义图像字段(在输入标记中带有 multiple
标志):
MODELS.PY
class Media(AbstractCreatedUpdatedDateMixin):
uuid = models.UUIDField(unique=True, default=uuid4, editable=False, db_index=True)
user = models.ForeignKey(User, related_name="uploaded_media", on_delete=models.CASCADE)
title = models.CharField(max_length=255)
image = models.ImageField(upload_to=uuid_directory_path)
ADMIN.PY
class MediaModelAdmin(admin.ModelAdmin):
def add_view(self, request, form_url='', extra_context=None):
self.exclude = ('image', "is_approved")
extra_context = extra_context or {}
extra_context['show_save_and_add_another'] = False
extra_context['show_save_and_continue'] = False
return super().add_view(request, form_url, extra_context)
def save_model(self, request, obj, form, change):
for file in request.FILES.values():
obj.user = User.objects.filter(id=request.POST.get("user")).first()
obj.title = request.POST.get("title")
obj.image.save(file.name, file.file)
obj.save()
它正确上传到S3,但它不会保存实例并抛出此错误:
TypeError at /admin/media/media/add/
expected string or bytes-like object
我不确定这里出了什么问题,也许上传尚未完成,因此数据库事务已回滚,但我无法弄清楚出去做什么。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试改变这一点
到
Try to change this
to
一段时间后我发现了这个问题。我没有在 request.FILES.values() 中使用
for file
甚至在save_model
中设置它,而是创建了一个单独的表单(代码如下)并覆盖了add_view
方法中的 >self.form 属性。这里的主要问题是尝试访问 request.FILES.values()。我不知道为什么,但如果您尝试访问文件列表,它只会返回一个文件。
您需要使用 self.files.getlist("image") 才能正确检索文件数组。
这发生在 Django 3.2 中,所以我不确定它是否在新版本中得到修复。
After some time I found out the issue. Instead of using
for file in request.FILES.values()
or even setting this in thesave_model
I've created a separate Form (code below) and overwrited theself.form
attribute in theadd_view
method of the ModelAdmin class.The main issue here was trying to access request.FILES.values(). I'm not sure why but if you try to access a list of files it'll return just a single file.
You need to use self.files.getlist("image") in order to correctly retrieve an array of the files.
This happened in Django 3.2, so I'm not sure if it's fixed in newer versions.