将Django的FileField设置为一个现有的文件
我有一个现有的文件在磁盘(说/folder/file.txt)和Django的FileField模型字段。
当我做
instance.field = File(file('/folder/file.txt')) instance.save()
它将文件重新保存为file_1.txt
(下一次是_2
等)。
我明白为什么,但我不想要这样的行为 – 我知道我想要的字段关联的文件真的在等着我,我只是想让Django指向它。
怎么样?
如果你想永久这样做,你需要创build自己的FileStorage类
from django.core.files.storage import FileSystemStorage class MyFileStorage(FileSystemStorage): # This method is actually defined in Storage def get_available_name(self, name): return name # simply returns the name passed
现在在你的模型中,使用你修改的MyFileStorage
from mystuff.customs import MyFileStorage mfs = MyFileStorage() class SomeModel(model.Model): my_file = model.FileField(storage=mfs)
只需将instance.field.name
设置为文件的path即可
例如
class Document(models.Model): file = FileField(upload_to=get_document_path) description = CharField(max_length=100) doc = Document() doc.file.name = 'path/to/file' # must be relative to MEDIA_ROOT doc.file <FieldFile: path/to/file>
试试这个( doc ):
instance.field.name = <PATH RELATIVE TO MEDIA_ROOT> instance.save()
编写自己的存储类是正确的。 但是, get_available_name
不是正确的重写方法。
当Django看到一个同名的文件并试图获得一个新的可用文件名时, get_available_name
被调用。 这不是导致重命名的方法。 引起的方法是_save
。 在_save
中的_save
是相当不错的,你可以很容易地find它打开文件用os.O_EXCL
标志写,如果相同的文件名已经存在,将会抛出一个OSError。 Django捕获这个错误然后调用get_available_name
来获得一个新的名字。
所以我认为正确的方法是重写_save
并调用没有os.O_EXCL
标志的os.O_EXCL
()。 修改很简单,但方法有点长,所以我不把它粘贴在这里。 告诉我,如果你需要更多的帮助:)
我有完全相同的问题! 那么我意识到我的模特造成了这一点。 例如我喜欢这样的模型:
class Tile(models.Model): image = models.ImageField()
然后,我想有更多的磁盘引用相同的文件的磁贴! 我发现解决这个问题的方法是将我的模型结构更改为:
class Tile(models.Model): image = models.ForeignKey(TileImage) class TileImage(models.Model): image = models.ImageField()
后来我意识到这是更有意义的,因为如果我想要保存更多的同一个文件在我的数据库中,我必须创build另一个表!
我想你也可以解决你的问题,只是希望你可以改变模型!
编辑
另外我猜你可以使用不同的存储,比如:SymlinkOrCopyStorage
http://code.welldev.org/django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py