Установите Django FileField в существующий файл
У меня есть существующий файл на диске (скажем/folder/file.txt) и поле модели FileField в Django.
Когда я делаю
instance.field = File(file('/folder/file.txt'))
instance.save()
он повторно сохраняет файл как file_1.txt
(в следующий раз он _2
и т.д.).
Я понимаю, почему, но я не хочу этого поведения. Я знаю, что файл, с которым я хочу связать поле, действительно ждет меня, и я просто хочу, чтобы Django указывал на него.
Как?
Ответы
Ответ 1
Если вы хотите сделать это навсегда, вам нужно создать свой собственный класс 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)
Ответ 2
просто установите instance.field.name
на путь вашего файла
например.
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>
Ответ 3
попробуйте это (doc):
instance.field.name = <PATH RELATIVE TO MEDIA_ROOT>
instance.save()
Ответ 4
Правильно написать собственный класс хранения. Однако get_available_name
не подходит для переопределения.
get_available_name
вызывается, когда Django видит файл с тем же именем и пытается получить новое доступное имя файла. Это не метод, который вызывает переименование. метод вызвал это _save
. Комментарии в _save
довольно хороши, и вы можете легко найти, что он открывает файл для записи с флагом os.O_EXCL
, который выдает OSError, если такое же имя файла уже существует. Django ловит эту ошибку, затем вызывает get_available_name
, чтобы получить новое имя.
Итак, я думаю, что правильный способ - переопределить _save
и вызвать os.open() без флага os.O_EXCL
. Модификация довольно проста, но метод немного длинный, поэтому я не вставляю его здесь. Скажите мне, если вам нужна дополнительная помощь:)
Ответ 5
У меня была такая же проблема! то я понимаю, что мои Модели вызывали это. Например, у меня были такие модели:
class Tile(models.Model):
image = models.ImageField()
Затем я хотел иметь больше одной плитки, ссылающейся на тот же файл на диске! Способ, которым я решил это решить, заключался в изменении моей структуры модели:
class Tile(models.Model):
image = models.ForeignKey(TileImage)
class TileImage(models.Model):
image = models.ImageField()
Что после того, как я понял, что имеет больше смысла, потому что, если я хочу, чтобы один и тот же файл был сохранен больше, чем один в моей БД, мне нужно создать для него другую таблицу!
Я думаю, вы тоже можете решить свою проблему, просто надеясь, что вы сможете изменить модели!
ИЗМЕНИТЬ
Также я предполагаю, что вы можете использовать другое хранилище, например, это: SymlinkOrCopyStorage
http://code.welldev.org/django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py