Login

Clone model mixin

Author:
zakj
Posted:
December 31, 2008
Language:
Python
Version:
1.0
Tags:
model mixin copy clone clonable
Score:
6 (after 6 ratings)

Add this as a superclass of any Django model to allow making copies of instances of that model:

class Entry(models.Model, CloneableMixin):
    [...]

e = Entry.objects.get(...)
e_clone = e.clone()
e_clone.title = 'Cloned Entry'
e.save()

The new object is saved during the clone process and ManyToMany relations are copied as well.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import copy


class ClonableMixin(object):
    def clone(self):
        """Return an identical copy of the instance with a new ID."""
        if not self.pk:
            raise ValueError('Instance must be saved before it can be cloned.')
        duplicate = copy.copy(self)
        # Setting pk to None tricks Django into thinking this is a new object.
        duplicate.pk = None
        duplicate.save()
        # ... but the trick loses all ManyToMany relations.
        for field in self._meta.many_to_many:
            source = getattr(self, field.attname)
            destination = getattr(duplicate, field.attname)
            for item in source.all():
                destination.add(item)
        return duplicate

More like this

Comments

rizumu (on October 22, 2009):
<p>On django 1.2, this snippet works for me only if i set both pk and id to None:</p> <pre># Setting both pk and id to None tricks Django into thinking this is a new object. duplicate.pk = None duplicate.id = None </pre>

#

Please login first before commenting.