[Django]-Copying files from one model to another


It strange thing. Now the way I tryed before works perfectly, without any errors.
Maybe I missed something at the first time. So it works:

from django.core.files import File
B.objects.create(attachment=File(open(a.attachment.path, 'rb')))


I had the same problem and solved it like this, hope it helps anybody:

# models.py

class A(models.Model):
    # other fields...
    attachment = FileField(upload_to='a')

class B(models.Model):
    # other fields...
    attachment = FileField(upload_to='b')

# views.py or any file you need the code in

    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
from django.core.files.base import ContentFile
from main.models import A, B

obj1 = A.objects.get(pk=1)

# You and either copy the file to an existent object
obj2 = B.objects.get(pk=2)

# or create a new instance
obj2 = B(**some_params)

tmp_file = StringIO(obj1.attachment.read())
tmp_file = ContentFile(tmp_file.getvalue())
url = obj1.attachment.url.split('.')
ext = url.pop(-1)
name = url.pop(-1).split('/')[-1]  # I have my files in a remote Storage, you can omit the split if it doesn't help you
tmp_file.name = '.'.join([name, ext])
obj2.attachment = tmp_file

# Remember to save you instance


Your code is working, but doesn’t create a new file.

For creating a new file, you should consider shutil.copy() : http://docs.python.org/library/shutil.html

Moreover, if you copy a file, its name has to be different from the previous one, or you can keep the same name if you create the file in another directory. It Depends what you want…

So your code becomes :

from shutil import copy
B.objects.create(attachment=copy(a.attachment.path, 'my_new_path_or_my_new_filename'))

Also don’t forget to .save() your new object.

Leave a comment