3

Each user has many albums, and each album has its many photos. And each user has one set background image to hold its many images. Similarly, a user has one set of profile picture to hold its many images.

These are my models:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    permanent_address = models.TextField()
    temporary_address = models.TextField()
    profile_pic = models.ForeignKey(ProfilePicture)
    background_pic = models.ForeignKey(BackgroundImage)


class Album(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)


class Photo(models.Model):
    album = models.ForeignKey(Album, default=3)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)


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)

Eg: I tried doing this: to let the user copy one image from ProfilePicture to Background Image, but didn't work:

# Get the user
>>>m = User.objects.get(username='m')

# Get its set of Profile pictures
>>>m_pro_set = m.profilepicture_set.all()
>>>m_pro_set
[<ProfilePicture: pro_mik>]

# Get its set of Background images
>>>m_back_set = m.backgroundimage_set.all()
>>>m_back_set
[<BackgroundImage: bg_mik>]

# Get an image object from Profile picture of the user
>>>m_pro_1 = m.profilepicture_set.get(id=2)
>>>m_pro_1
<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>

# So, I tried to copy one image from BackgroundImage of a user to ProfilePicture

>>>m_pro_set.objects.create(m_back_1)

    File "<console>", line 1, object has attribute 'objects'
AttributeError: 'QuerySet' object has no attribute 'objects'

So my question is, how to copy an objects from one model to another? Any advice will be much appreciated.

1 Answer 1

4

You'll need to copy the properties of one object to another object. create is used when you want to create a new instance, not when you want to update a specific instance.

m_pro = m_pro_set[0] # m_pro_set is a list and need to get the specific instance
m_pro.image = m_back_1.image
m_pro.caption = m_back_1.caption
m_pro.pub_date = m_back_1.pub_date
m_pro.save()

Alternatively you can create a method on ProfilePicture if this is a common operation to contain this functionality.

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)

    def update(self, bg_img):
        self.image = bg_img.image
        self.caption = bg_img.caption
        self.pub_date = bg_img.pub_date
        self.save()

So you would just need to call m_pro_1.update(m_back_1) if we wanted to make m_pro_1 have the same properties as m_back_1

Also, if you wanted to create a new instance, I'd suggest using a classmethod like the following

class ProfilePicture(models.Model):
    ...

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

    @classmethod
    def create_from_photo(cls, photo):
        img = cls(user=photo.album.user, image=photo.image, caption=photo.caption, pub_date=photo.pub_date)
        img.save()
        return img

This creates a new ProfilePicture and is used: profile_pic = ProfilePicture.create_from_bg(m_back_1)

Sign up to request clarification or add additional context in comments.

10 Comments

Thank you for the answer! I tried the way its here. But I guess you got me wrong. What I want is to copy an image from one model and then create it in another model, but to leave the original image as it is. Hope I made it clear.
Use the classmethod approach. It's a factory function to generate a new object. You can create one for each of your types (referring to your comment on the other answer).
Oh! Am sorry. I didn't looked at it properly. I think its easier. But how do I create a new instance from model Photo to ProfilePic or to BackgroundImage. Is it the same procedure?
I added something to my answer to show you how that might look. Basically, you can use anything as your parameter as long as you can define the properties of your model from that.
Did this answer your question or do you need further clarification on something?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.