Establecer el FileField de Django en un archivo existente

Tengo un archivo existente en el disco (por ejemplo, /folder/file.txt) y un campo de modelo FileField en Django.

Cuando lo hago

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

vuelve a file_1.txt el archivo como file_1.txt (la próxima vez que sea _2 , etc.).

Entiendo por qué, pero no quiero este comportamiento. Sé que el archivo con el que quiero que se asocie el campo está realmente esperándome, y solo quiero que Django lo señale.

¿Cómo?

Si desea hacerlo de forma permanente, debe crear su propia clase 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 

Ahora en tu modelo, usas tu MyFileStorage modificado

 from mystuff.customs import MyFileStorage mfs = MyFileStorage() class SomeModel(model.Model): my_file = model.FileField(storage=mfs) 

simplemente establece instance.field.name a la ruta de tu archivo

p.ej

 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  

prueba esto ( doc ):

 instance.field.name =  instance.save() 

Es correcto escribir su propia clase de almacenamiento. Sin embargo, get_available_name no es el método correcto para anular.

Se llama a get_available_name cuando Django ve un archivo con el mismo nombre e intenta obtener un nuevo nombre de archivo disponible. No es el método que causa el cambio de nombre. El método que causó es _save . Los comentarios en _save son bastante buenos y puede encontrar fácilmente que abre un archivo para escribir con el indicador os.O_EXCL que lanzará un error OSE si ya existe el mismo nombre de archivo. Django atrapa este error y luego llama a get_available_name para obtener un nuevo nombre.

Así que creo que la forma correcta es anular _save y llamar a os.open () sin el indicador os.O_EXCL . La modificación es bastante simple, sin embargo, el método es un poco largo, así que no lo pegue aquí. Dime si necesitas más ayuda 🙂

¡Tuve exactamente el mismo problema! Entonces me doy cuenta de que mis modelos estaban causando eso. Ejemplo: Hade a mis modelos así:

 class Tile(models.Model): image = models.ImageField() 

Entonces, ¡quería tener más de una ficha haciendo referencia al mismo archivo en el disco! La forma en que lo encontré para resolver eso fue cambiar la estructura de mi Modelo a esto:

 class Tile(models.Model): image = models.ForeignKey(TileImage) class TileImage(models.Model): image = models.ImageField() 

Después de eso me doy cuenta de que tiene más sentido, porque si quiero que se guarde el mismo archivo más de uno en mi DB, ¡tengo que crear otra tabla para él!

Supongo que también puedes resolver tu problema así, ¡solo con la esperanza de que puedas cambiar los modelos!

EDITAR

También creo que puedes usar un almacenamiento diferente, como este, por ejemplo: SymlinkOrCopyStorage

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