Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - How to copy actual image file from one model to another?

I want to copy images from one model to another within the project. Suppose these are my models:

class BackgroundImage(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)


class ProfilePicture(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

    @classmethod
        def create_from_bg(cls, bg_img):
            img = cls(user=bg_img.user, image=bg_img.image, caption=bg_img.caption+'_copy', pub_date=bg_img.pub_date)
            img.save()
            return img

For now, I can do these:

To get the user

>>>m = User.objects.get(username='m')

To get the user's profile picture set

>>>m_pro_set = m.profilepicture_set.all()
>>>m_pro_set
[<ProfilePicture: pro_mik>]

Get an image object from Background image of the user

>>>m_back_1 = m.backgroundimage_set.get(id=2)
>>>m_back_1
<BackgroundImage: bg_mik>

And then:

>>>profile_pic = ProfilePicture.create_from_bg(m_back_1)

Now when I check it, it does create a new instance.

>>>m_pro_set
[<ProfilePicture: pro_mik>,<ProfilePicture: bg_mik>]

But, if I check on the path, and even on the media folder, its the same image and not an actual copy of the image file.

>>>profile_pic.image
<ImageFileField: uploaded_files/1389904144_ken.jpg>
>>>m_back_1.image
<ImageFileField: uploaded_files/1389904144_ken.jpg>

How do I go about, to actually copy the original image file within the models? Any help will be much appreciated! Thank you.

like image 723
Aamu Avatar asked Nov 08 '13 16:11

Aamu


2 Answers

so I know this question is pretty old, but hopefully this answer help someone...

My approach for doing this, uploading the photo to the proper path for the suggested model, is:

from django.core.files.base import ContentFile

picture_copy = ContentFile(original_instance.image.read())
new_picture_name = original_instance.image.name.split("/")[-1]
new_instance.image.save(new_picture_name, picture_copy)

Please check that in my case, the new name is just the same file name, but to be updated in the new model image field's path. In your case, depending on what you have inside "get_upload_file_name" it could leads to the same path again (since is used in both classes). Also you can create a new, random name.

Hope this helps someone =)

like image 121
Alessandro Odetti Avatar answered Nov 09 '22 18:11

Alessandro Odetti


  • Best & Short solution is that
existing_instance = YourModel.objects.get(pk=1)
new_instance.image = existing_instance.image

It's work fine for me.

like image 2
Ashish Sondagar Avatar answered Nov 09 '22 18:11

Ashish Sondagar