我已经阅读了有关此主题的其他问题,但实际上没有回答我的问题。
我让用户在向网站提交某个项目时上传图片。每个用户都可以提交多个项目,每个项目都有一张图片。
问题是,我不想用原始文件名保存图片。我想用项目的ID保存它。因此,如果用户提交了Banana项目,该项目的ID为5,文件名为
banana.jpg
我希望它保存为
site_media/items/5.jpg
而不是
site_media/items/banana.jpg
这是Django自动执行的操作。
现在的问题是,当我从表单中获取POST多部分数据时,我已经将图片保存为site_media / items / item_ID.jpg。但是,当我尝试在模板上显示字段item.picture时,它会尝试访问
site_media/items/banana.jpg
而不是
site_media/items/5.jpg
哪个是实际存在的文件。所以我得到了一个破碎的链接。
我试图更改picture.path属性,希望它只是Django在链接图像时读取的字符串,但是Django给了我一个异常,这让我觉得它可能是其他东西。
此外,我自然希望有一个解决方案,我只是在保存时更改文件名,而不是使用原始文件名删除文件并保存带有新名称的副本,以达到良好的实践和效率目的。< / p>
任何人都可以帮我这个吗?谢谢。
模型代码:
class Item(...):
...
picture = models.ImageField(
upload_to="site_media/items/",
max_length=512,
null=True,
default=''
)
以下是处理POST表单的函数:
item = Item.objects.create(... data from form)
try:
picture = FILES['picture']
print str(picture)
destination = open('site_media/items/'+str(item.id)+".png", 'wb+')
for chunk in picture.chunks():
destination.write(chunk)
destination.close()
item.picture = picture
except Exception:
messages.error(request, "Picture for item not loaded successfully")
答案 0 :(得分:6)
您可以在图像字段上提供对upload_to
参数的回调。将为将保存的当前实例提供指定的函数。见例如。 this example。
这个解决方案的问题是,一个新实例可能还没有Id,所以使用类似UUID之类的东西来生成文件名是有意义的,所以你也可以轻松避免冲突有一个实例的多个文件!看看python docs生成UUID!
答案 1 :(得分:1)
找到解决方案。因此,问题是request.FILES
包含与保存的文件名不同的文件名。所以我在保存图像之前只更改了request.FILES
文件名,如下所示:
picture = FILES['picture']
FILES['picture'].name = str(item.id) + '.png'
# ...save as normal