103 votes

Définir le champ de fichier de Django sur un fichier existant

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 sous file_1.txt (la prochaine fois, il s'agira de _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?

140voto

bara Points 817

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>
 

25voto

Burhan Khalid Points 50578

Si vous voulez le faire de manière permanente, vous devez créer votre propre classe FileStorage.

 from django.core.files.storage import FileSystemStorage

class MyFileStorage(FileSystemStorage):

    # This method is actually defined in Storage
    def get_available_name(self, 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)
 

19voto

uNmAnNeR Points 56

essayez ceci ( doc ):

 instance.field.name = <PATH RELATIVE TO MEDIA_ROOT> 
instance.save()
 

5voto

Zhang Xiao Points 126

C'est le droit d'écrire propre classe de stockage. Toutefois get_available_name n'est pas la bonne méthode pour remplacer la.

get_available_name est appelée lorsque Django voit un fichier avec le même nom et essaie d'obtenir un nouveau nom de fichier existant. Ce n'est pas la méthode qui provoque le changement de nom. la méthode causés c'est - _save. Commentaires en _save est très bonne et vous pouvez facilement le trouver s'ouvre en écriture du fichier avec l'indicateur os.O_EXCL qui va jeter un OSError si le même nom de fichier existe déjà. Django captures de cette Erreur, puis appelle get_available_name pour obtenir un nouveau nom.

Je pense donc que la bonne manière est de remplacer _save et l'appel de l'os.open() sans indicateur os.O_EXCL. La modification est assez simple, cependant, la méthode est un peu être long donc je n'ai pas le coller ici. Dites-moi si vous avez besoin de plus d'aide :)

1voto

Arthur Neves Points 5753

J'ai eu exactement le même problème! puis je me rends compte que mes Modèles étaient à l'origine de cela. exemple j'ai mes modèles comme ceci:

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

Ensuite, je voulais avoir plus d'une tuile de référence au même fichier dans le disque! Le moyen que j'ai trouvé pour y remédier a été de changer mon Modèle de structure:

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

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

Qui, après je me rends compte que plus de sens, parce que si je veux le même fichier enregistré plus d'un dans ma DB j'ai créer une autre table!

Je suppose que vous pouvez résoudre votre problème comme ça aussi, en espérant que vous pouvez modifier les modèles de!

MODIFIER

Aussi, je suppose que vous pouvez en utiliser un autre, comme ceci par exemple: SymlinkOrCopyStorage

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X