简体   繁体   中英

copy of a Django model instance along with a related One-to-One field

How do I create a copy of a Django model instance along with a related One-to-One field?

Copying the model instance works fine, but when I try to create a copy of the one-to-one model, all the fields of that model become blank. Here's what I did:

            new_address = self.object.designer.address # type Address
            new_address.pk = None
            new_address.save()

            new_contact = self.object.designer # type Contact
            new_contact.pk = None
            new_contact.address = new_address

            new_contact.save()

            self.object.shippinginfo.contact = new_contact
            self.object.shippinginfo.save()

The Contact model has a one-to-one relationship with the Address model. I tried printing out the values, after creating the new address, the values were correct when I printed them out, but then when I save the address to the address field of the new contact, all of the fields of the address are blank except the pk...

I think you're not clear about how to define relationship. If Contact model has one to one relationship with Address model, then one object of Contact class can be related to one object of Address model. It'll be defined as:

class Contact(models.Model):
    # field_one = ...
    # field_two = ...
    # and so on...

class Address(models.Model):
    contact = OneToOneField(Contact)
    # and more model fields...

This way you can associate one Contact object to one Address object. If you want to have more than one address for one contact then you should use ForeignKey .

For one Contact object having related to many Address instances, you can define relationship as:

class Contact(models.Model):
   # field_one = ...
   # field_two = ...
   # and so on...

class Address(models.Model):
    contact = ForeignKey(Contact)
    # and more fields...

But here an Address object can be associated to a particular Contact object only.

You can read about Many To Many realtionship here.

And you don't have to initialize pk field as it is automatically updated/added.

To answer your direct question, you may want to use the save(force_insert=True) function and see if that fixes it. I would also check what you get if you call Contact.objects.all().count() and the same for Address, so you can ensure you are adding new records.

That said, I personally will recommend against what you are trying to do, which in my book, is a hack. Instead, just write the few extra lines of code and properly call the Adress.objects.create() and Contact.objects.create with the fields set from the other records. eg

old_address = self.object.designer.address
new_address = Address.objects.create(line1=old_adress.line1, line2=old_address.line2, etc)

Or even better, use an AddressManager :

class AddressManager(models.Manager):
    def create_copy(self, obj):
        address = self.create(line1=obj.line1, etc.)
        return address

class ContactManager(models.Manager):
    def create_copy(self, obj):
        new_address = Address.objects.create_copy(obj.address)
        contact = self.create(name=obj.name, address=new_address, etc.)
        return contact

new_contact = Contact.objects.create_copy(old_contact)

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM