Установите 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