Set Django's FileField to an existing file

just set instance.field.name to the path of your file

e.g.

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>

If you want to do this permanently, you need to create your own FileStorage class

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

Now in your model, you use your modified MyFileStorage

from mystuff.customs import MyFileStorage

mfs = MyFileStorage()

class SomeModel(model.Model):
   my_file = model.FileField(storage=mfs)

try this (doc):

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

It's right to write own storage class. However get_available_name is not the right method to override.

get_available_name is called when Django sees a file with same name and tries to get a new available file name. It's not the method that causes the rename. the method caused that is _save. Comments in _save is pretty good and you can easily find it opens file for writing with flag os.O_EXCL which will throw an OSError if same file name already exists. Django catches this Error then calls get_available_name to get a new name.

So I think the correct way is to override _save and call os.open() without flag os.O_EXCL. The modification is quite simple however the method is a little be long so I don't paste it here. Tell me if you need more help :)


I had exactly the same problem! then I realize that my Models were causing that. example I hade my models like this:

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

Then, I wanted to have more the one tile referencing the same file in the disk! The way that I found to solve that was change my Model structure to this:

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

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

Which after I realize that make more sense, because if I want the same file being saved more then one in my DB I have to create another table for it!

I guess you can solve your problem like that too, just hoping that you can change the models!

EDIT

Also I guess you can use a different storage, like this for instance: SymlinkOrCopyStorage

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