在Django FileField中重命名文件

14

我知道这里有一个非常相似的帖子,但是我找不到解决我的问题的方法。

我需要重命名一个保存在Django模型FileField中的文件。

我尝试了这个

os.rename(old_path, new_path)
mod.direct_file = File(open(new_path))
mod.save()

而且这个

mod.direct_file.save(new_path, File(open(old_path)))
os.remove(old_path)

还有许多其他方法,但似乎没有什么有用。无论使用哪种方式创建新文件,文件字段中的数据都不会改变。

编辑:问题已解决

os.rename(old_path, new_path)
cursor = connection.cursor()
cursor.execute("UPDATE mods_mod SET direct_file = %s WHERE id = %s", [new_name, mod.id])
transaction.commit_unless_managed()
6个回答

17

我认为你不需要使用原始SQL来完成这个任务。我认为你需要使用os工具来重命名文件,然后将模型的FileField名称设置为新名称。可能类似于:

os.rename(model.direct_file.path, new_path)
model.direct_file.name = new_name
model.save()

1
只有在使用 FileSystemStorage 时才能正常工作。 - WhyNotHugo

5
 new_name = 'photos_preview/' + str(uuid.uuid1())
 os.rename(photo.image_preview.path, settings.MEDIA_ROOT + new_name)
 photo.image_preview.name = new_name
 photo.save()

3
当前 Django 文档中指出:
当您在模型上访问 FileField 时,会得到一个 FieldFile 实例作为访问底层文件的代理。请参阅 docs 以进行进一步阅读。
您应该使用 FieldFile.open() 打开文件,而不是使用 Python 文件对象打开文件,然后相应地操作文件路径。之后,保存模型对象,路径的更改就应该持久化了。

Open方法打开已分配的文件。FieldFile没有打开另一个文件的方法。 - aemdy
文件是通过FileField分配的,对吗?您是想更改模型中的所有文件还是单个模型实例? - droxey
我想要重命名在这个字段上传的文件 direct_file = models.FileField(default=None, blank=True, null=True, upload_to="mod_files") - aemdy
我仍然不清楚您是想重命名模型字段“direct_file”,还是想重命名存储在文件系统上的实际文件。我的答案适用于尝试重命名存储在文件系统上的文件。 - droxey
我想在文件系统中重命名文件。 - aemdy

1
你可以使用以下代码:
假设“obj”是你想要重命名的Django对象,请执行以下操作:
obj.file_field_name.name = new_name

obj.save()


文件不会被移动,只是名称会有所不同。 - wieczorek1990

1
我在将没有文件扩展名的Blob保存到Django中时遇到了这个问题,并且希望进行更正。最好在循环筛选查询集时使用。
您无法更改instance.picture.path,并且尝试访问instance.picture.file.*会导致错误,因为访问它将尝试打开旧文件。设置instance.picture.name仍然无法让您访问instance.picture.file.*,即使在保存后也是如此。
您可以简单地将ImageField对象本身设置为位置,所有内容都将正常工作:
(已在django 1.10中测试)
import imghdr
import os

from django.db import models

class MyModel(models.Model):
    picture = models.ImageField()

instance = MyModel.objects.first()
if os.path.exists(instance.picture.path):
    extension = imghdr.what(instance.picture.path)
    os.rename(instance.picture.path, instance.picture.path + '.' + extension)
    instance.picture = instance.picture.name + '.' + extension
    instance.save()

0

根据 Django 文档,似乎在 FileField 中更改二进制文件的文件名非常不灵活。它包含从媒体根目录开始的路径。 这指出了一个反映路径而不仅仅是文件名本身的名称属性。文档:这是 Django 模型找到文件的方法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接