Установите поле файла Django в существующий файл
у меня есть существующий файл на диске (скажем файл /папка/.txt) и поле модели FileField в Django.
когда я делаю
instance.field = File(file('/folder/file.txt'))
instance.save()
он повторно сохраняет файл как file_1.txt
(в следующий раз это _2
и т. д.).
Я понимаю, почему, но я не хочу такого поведения - я знаю, что файл, с которым я хочу связать поле, действительно ждет меня, и я просто хочу, чтобы Django указал на него.
как?
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