Установить FileField Django в существующий файл - PullRequest
77 голосов
/ 01 декабря 2011

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

Когда я делаю

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

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

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

Как?

Ответы [ 5 ]

98 голосов
/ 06 июня 2012

просто укажите 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>
18 голосов
/ 01 декабря 2011

Если вы хотите сделать это навсегда, вам нужно создать свой собственный класс 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)
9 голосов
/ 23 августа 2013

попробуйте это ( документ ):

instance.field.name = <PATH RELATIVE TO MEDIA_ROOT> 
instance.save()
4 голосов
/ 23 марта 2012

Правильно написать собственный класс хранения. Однако get_available_name не является правильным методом для переопределения.

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

Так что я думаю, что правильный путь - переопределить _save и вызвать os.open () без флага os.O_EXCL. Модификация довольно проста, однако метод немного длинный, поэтому я не вставляю его сюда. Скажите, если вам нужна дополнительная помощь:)

0 голосов
/ 01 декабря 2011

У меня была точно такая же проблема! потом я понимаю, что мои модели были причиной этого. Пример, который я привел в пример своим моделям:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...