Skip to content
This repository was archived by the owner on Mar 6, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion django_cloneable/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def _clone_copy(self):
import copy
if not self.instance.pk:
raise ValueError('Instance must be saved before it can be cloned.')
return copy.copy(self.instance)
duplicate = copy.copy(self.instance)
duplicate._state = models.base.ModelState()
return duplicate

def _clone_prepare(self, duplicate, exclude=None):
# Setting pk to None tricks Django into not trying to overwrite the old
Expand Down
7 changes: 6 additions & 1 deletion tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ class ModelWithFields(CloneableMixin, models.Model):
integer = models.IntegerField(default=0)
date = models.DateField(default=date(2000, 1, 1))


class ModelWithCustomPK(CloneableMixin, models.Model):
key = models.CharField(max_length=50, primary_key=True)
value = models.IntegerField()

class RelatedModel(models.Model):
pass

class ModelWithFK(CloneableMixin, models.Model):
related = models.ForeignKey(RelatedModel, related_name='+', null=True, on_delete=models.SET_NULL)
12 changes: 12 additions & 0 deletions tests/test_cloneable.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from .models import ModelWithCustomPK
from .models import ModelWithFields
from .models import RelatedModel
from .models import ModelWithFK


class CloneableTests(TestCase):
Expand All @@ -27,3 +29,13 @@ def test_must_provide_new_pk_if_its_custom_field(self):
assert i2.pk == 'bar'
assert i1.pk != i2.pk
assert i2.value == 42

def test_cloning_object_allows_overwriting_fk_reference(self):
i1 = ModelWithFK.objects.create()
i1.related = RelatedModel.objects.create()
i1.save()

i2 = i1.clone()
i2.related = RelatedModel.objects.create()
i2.save()
assert i1.related != i2.related