Django - 在ImageField上更改文件名

时间:2011-12-14 22:30:50

标签: django django-models

我已经阅读了有关此主题的其他问题,但实际上没有回答我的问题。

我让用户在向网站提交某个项目时上传图片。每个用户都可以提交多个项目,每个项目都有一张图片。

问题是,我不想用原始文件名保存图片。我想用项目的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")

2 个答案:

答案 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