1

I have a this model...

class MyModel(models.Model):
    ...
    file = models.FileField(upload_to='files/',null=True, blank=True)
    ...

when i upload a file, example file name is docfile.doc. when i change the file or i rewrite it and upload again docfile.doc the file will become docfile_1.doc and the old docfile.doc is still exist.

i am doing the uploading and saving data in django-admin

my question is, how can i remove the old docfile.doc if i upload the new docfile.doc and the file name is still docfile.doc?

can anyone help me in my case? thanks in advance

i try this one :

def content_file_name(instance, filename):
    print instance
    print filename
    file = os.path.exists(filename)
    print file
    if file:
        os.remove(filename)
    return "file/"+str(filename)

 class MyModel(models.Model):
        ...
        file = models.FileField(upload_to=content_file_name,null=True, blank=True)
        ...

but nothing happend, when i upload docfile.doc again, it will become docfile_1.doc and the old docfile.doc still exist.

gadss
  • 21,687
  • 41
  • 104
  • 154

4 Answers4

2

i got it... i use this

def content_file_name(instance, filename):
    print instance
    print filename
    file = os.path.exists("media/file/"+str(filename))
    print file
    if file:
        os.remove("media/file/"+str(filename))
    return "file/"+str(filename)
gadss
  • 21,687
  • 41
  • 104
  • 154
2

I don't know exactly how to do it, but i think these links can help you:

Here you can find the two options that a FileField accept. The one that i think will interest you the most is FileField.storage. You can pass a storage object in that parameter.

It says:

FileField.storage: Optional. A storage object, which handles the storage and retrieval of your files.

Then, if you read this you would see that you can write your own storage object. Here is some explanation on how to do it. I think that you could just override the _save method in order to accomplish what you want to do (i.e: if the file already exists, remove it before saving the new copy.)

But be careful! I don't know which is the source of the files you are going to store. Maybe, your app is going to recieve lots of files with the same name, although they are all different. In this case, you would want to use a callable as the FileField.upload_to parameter, so that determine a unique filename for each file your site recieve.

I hope this helps you!

marianobianchi
  • 8,238
  • 1
  • 20
  • 24
0

You could also have a look here: ImageField overwrite image file with same name

Define your own storage and overwrite its get available_name method.

Community
  • 1
  • 1
Jingo
  • 3,200
  • 22
  • 29
0

The next code solves your problem. You override pre_save method where image is actually saved to storage. Please, rename functions for your project. Use newly created image field ImageFieldWithPermantName with your upload_to function (content_file_name).

If the code is too complicated you could simplify it. I use the code to do more complex operations for uploading images: I create thumbnails on-the-fly in custom _save_image function. So, you can simplify it.

from PIL import Image
import StringIO
from django.db.models import ImageField
from django.db.models.fields.files import FileField
from dargent.settings import MEDIA_ROOT
import os

class ImageFieldWithPermanentName( ImageField ):
    def pre_save( self, model_instance, add ):
        file = super( FileField, self ).pre_save(model_instance, add)
        if file and not file._committed:
            if callable( self.upload_to ):
                path = self.upload_to( model_instance, "" )
            else:
                path = self.upload_to
            file.name = path # here we set the same name to a file
            path = os.path.join( MEDIA_ROOT, path )
            chunks = _get_chunks( file.chunks() )
            _save_image( chunks, path )

        return file     

def _get_chunks( chunks ):
    chunks_ = ""
    for chunk in chunks:
        chunks_ += chunk
    return chunks_

def _get_image( chunks ):
    chunks_ = ""
    for chunk in chunks:
        chunks_ += chunk

    virt_file = StringIO.StringIO( chunks_ )
    image = Image.open( virt_file )
    return image

def _save_image( chunks, out_file_path ):
    image = _get_image( chunks )
    image.save( out_file_path, "JPEG", quality = 100 )
sergzach
  • 6,578
  • 7
  • 46
  • 84