Установите поле файла Django в существующий файл


у меня есть существующий файл на диске (скажем файл /папка/.txt) и поле модели FileField в Django.

когда я делаю

instance.field = File(file('/folder/file.txt'))
instance.save()

он повторно сохраняет файл как file_1.txt (в следующий раз это _2 и т. д.).

Я понимаю, почему, но я не хочу такого поведения - я знаю, что файл, с которым я хочу связать поле, действительно ждет меня, и я просто хочу, чтобы Django указал на него.

как?

5 68

5 ответов:

Если вы хотите сделать это постоянно, вам нужно создать свой собственный класс FileStorage

import os
from django.conf import settings
from django.core.files.storage import FileSystemStorage

class MyFileStorage(FileSystemStorage):

    # This method is actually defined in Storage
    def get_available_name(self, name):
        if self.exists(name):
            os.remove(os.path.join(settings.MEDIA_ROOT, 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 к пути вашего файла

например

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 Это не правильный метод, чтобы переопределить.

get_available_name вызывается, когда Django видит файл с тем же именем и пытается получить новое доступное имя файла. Это не метод, который вызывает переименование. метода вызвано тем, что составляет _save. Комментарии в _save довольно хорошо, и вы можете легко найти его открывает файл для записи с флагом os.O_EXCL который бросит OSError, если такое же имя файла уже существует. Django ловит эту ошибку тогда звонит get_available_name чтобы получить новое имя.

поэтому я думаю, что правильный способ, чтобы переопределить _save и вызова операционной системы.открыть() без флага 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()

который после того, как я понимаю, что это имеет больше смысла, потому что если я хочу, чтобы один и тот же файл был сохранен более одного в моей БД, я должен создать для него другую таблицу!

Я думаю, вы можете решить вашу проблему, как это тоже, просто надеясь, что вы можете изменить модели!

EDIT

также я думаю, что вы можете использовать другое хранилище, например: SymlinkOrCopyStorage

http://code.welldev.org/django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py