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

  1. Clone method for Django models by nside 6 years, 9 months ago
  2. GeoDjango maps in admin TabularInlines by alanB 4 years, 6 months ago
  3. ModelMixin by eallik 4 years, 5 months ago
  4. Test runner that installs 'tests' packages as apps by adrian_lc 1 year, 6 months ago
  5. Copy/Paste form generation by dballanc 7 years, 5 months ago

Comments

rizumu (on October 22, 2009):

On django 1.2, this snippet works for me only if i set both pk and id to None:

# Setting both pk and id to None tricks Django into thinking this is a new object.
duplicate.pk = None
duplicate.id = None

#

Please login first before commenting.