The Python Oracle

How do I clone a Django model instance object and save it to the database?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Techno Bleepage Open

--

Chapters
00:00 Question
00:34 Accepted answer (Score 612)
00:59 Answer 2 (Score 157)
02:42 Answer 3 (Score 56)
03:20 Answer 4 (Score 49)
03:35 Thank you

--

Full question
https://stackoverflow.com/questions/4733...

Accepted answer links:
[here]: https://docs.djangoproject.com/en/dev/re...
https://docs.djangoproject.com/en/2.2/to...

Answer 2 links:
[a section on copying model instances]: https://docs.djangoproject.com/en/stable...
[this ticket]: https://code.djangoproject.com/ticket/40...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #django #djangomodels

#avk47



ACCEPTED ANSWER

Score 662


Just change the primary key of your object and run save().

obj = Foo.objects.get(pk=<some_existing_pk>)
obj.pk = None
obj.save()

If you want auto-generated key, set the new key to None.

More on UPDATE/INSERT here.

Official docs on copying model instances: https://docs.djangoproject.com/en/2.2/topics/db/queries/#copying-model-instances




ANSWER 2

Score 169


The Django documentation for database queries includes a section on copying model instances. Assuming your primary keys are autogenerated, you get the object you want to copy, set the primary key to None, and save the object again:

blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1

blog.pk = None
blog.save() # blog.pk == 2

In this snippet, the first save() creates the original object, and the second save() creates the copy.

If you keep reading the documentation, there are also examples on how to handle two more complex cases: (1) copying an object which is an instance of a model subclass, and (2) also copying related objects, including objects in many-to-many relations.


Note on miah's answer: Setting the pk to None is mentioned in miah's answer, although it's not presented front and center. So my answer mainly serves to emphasize that method as the Django-recommended way to do it.

Historical note: This wasn't explained in the Django docs until version 1.4. It has been possible since before 1.4, though.

Possible future functionality: The aforementioned docs change was made in this ticket. On the ticket's comment thread, there was also some discussion on adding a built-in copy function for model classes, but as far as I know they decided not to tackle that problem yet. So this "manual" way of copying will probably have to do for now.




ANSWER 3

Score 67


Be careful here. This can be extremely expensive if you're in a loop of some kind and you're retrieving objects one by one. If you don't want the call to the database, just do:

from copy import deepcopy

new_instance = deepcopy(object_you_want_copied)
new_instance.id = None
new_instance.save()

It does the same thing as some of these other answers, but it doesn't make the database call to retrieve an object. This is also useful if you want to make a copy of an object that doesn't exist yet in the database.




ANSWER 4

Score 23


There's a clone snippet here, which you can add to your model which does this:

def clone(self):
  new_kwargs = dict([(fld.name, getattr(old, fld.name)) for fld in old._meta.fields if fld.name != old._meta.pk]);
  return self.__class__.objects.create(**new_kwargs)