J'ai un fichier existant sur le disque (par exemple, /folder/file.txt) et un champ de modèle FileField dans Django.
Quand je fais
instance.field = File(file('/folder/file.txt'))
instance.save()
il ré-enregistre le fichier en tant que file_1.txt
(la prochaine fois que ce sera _2
, etc.).
Je comprends pourquoi, mais je ne veux pas ce comportement - je sais que le fichier auquel je souhaite associer le champ est vraiment là, et je veux juste que Django le pointe du doigt.
Comment?
Si vous voulez le faire de manière permanente, vous devez créer votre propre classe 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
Maintenant, dans votre modèle, vous utilisez votre MyFileStorage modifié
from mystuff.customs import MyFileStorage
mfs = MyFileStorage()
class SomeModel(model.Model):
my_file = model.FileField(storage=mfs)
il suffit de définir instance.field.name
sur le chemin de votre fichier
par exemple.
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>
essayez ceci ( doc ):
instance.field.name = <PATH RELATIVE TO MEDIA_ROOT>
instance.save()
C'est juste d'écrire sa propre classe de stockage. Cependant, get_available_name
n'est pas la bonne méthode à remplacer.
get_available_name
est appelé lorsque Django voit un fichier portant le même nom et tente d'obtenir un nouveau nom de fichier disponible. Ce n'est pas la méthode qui provoque le changement de nom. la méthode qui a provoqué est _save
. Les commentaires dans _save
sont plutôt bons et vous pouvez facilement le trouver. Ce fichier ouvre l'écriture avec l'indicateur os.O_EXCL
qui génère une erreur OSError si le même nom de fichier existe déjà. Django attrape cette erreur puis appelle get_available_name
pour obtenir un nouveau nom.
Donc, je pense que la bonne façon est de remplacer _save
et d'appeler os.open () sans l'indicateur os.O_EXCL
. La modification est assez simple mais la méthode est un peu longue, donc je ne la colle pas ici. Dis-moi si tu as besoin de plus d'aide :)
J'ai eu exactement le même problème! alors je me rends compte que mes modèles causaient ça. Par exemple, j'ai mes modèles comme ceci:
class Tile(models.Model):
image = models.ImageField()
Ensuite, je voulais avoir plus d'une tuile référençant le même fichier sur le disque! La façon dont j'ai trouvé pour résoudre cela a été de changer la structure de mon modèle en ceci:
class Tile(models.Model):
image = models.ForeignKey(TileImage)
class TileImage(models.Model):
image = models.ImageField()
Ce qui après, je réalise que cela a plus de sens, parce que si je veux que le même fichier soit sauvegardé plus d'un fichier dans ma base de données, je dois créer un autre tableau pour cela!
Je suppose que vous pouvez également résoudre votre problème de cette manière, en espérant simplement pouvoir changer de modèle!
MODIFIER
Aussi, je suppose que vous pouvez utiliser un stockage différent, comme par exemple: SymlinkOrCopyStorage
http://code.welldev.org/Django-storages/src/11bef0c2a410/storages/backends/symlinkorcopy.py