diff --git a/django_cloneable/models.py b/django_cloneable/models.py index 9fa9664..65036c0 100644 --- a/django_cloneable/models.py +++ b/django_cloneable/models.py @@ -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 diff --git a/tests/models.py b/tests/models.py index b62b657..447cbf6 100644 --- a/tests/models.py +++ b/tests/models.py @@ -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) \ No newline at end of file diff --git a/tests/test_cloneable.py b/tests/test_cloneable.py index 6ebdfb0..d242847 100644 --- a/tests/test_cloneable.py +++ b/tests/test_cloneable.py @@ -3,6 +3,8 @@ from .models import ModelWithCustomPK from .models import ModelWithFields +from .models import RelatedModel +from .models import ModelWithFK class CloneableTests(TestCase): @@ -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 \ No newline at end of file