Repository: tj-django/django-clone

Issue:
Doesn't duplicate with custom `id`
A model with a custom `id` field is not duplicated:

the `Branch` model has the id `id = models.UUIDField(primary_key=True, default=uuid4)`

```
>>> base_branch = Branch.objects.create(name='Main branch', parent=None, is_master=True, status=Branch.DRAFT)
>>> base_branch.pk
UUID('7a613f9d-90fe-4116-b897-69505cd4ff5c')
>>> clone = base_branch.make_clone()
>>> clone.pk
UUID('7a613f9d-90fe-4116-b897-69505cd4ff5c')
```

I think this is because the custom id shows up in `_meta.concrete_fields` the value is copied over, preventing it from generating a new PK. 

```
>>> base_branch._meta.concrete_fields
(<django.db.models.fields.UUIDField: id>, <django.db.models.fields.CharField: name>, <django.db.models.fields.BooleanField: is_master>, <django.db.models.fields.related.ForeignKey: parent>, <django.db.models.fields.CharField: status>)
```
The primary key field can be found through `instance._meta.pk`, filtering this out of the fields to copy should resolve this problem I think.


Discussion:

Resolving patch:
diff --git a/model_clone/mixins/clone.py b/model_clone/mixins/clone.py
--- a/model_clone/mixins/clone.py
+++ b/model_clone/mixins/clone.py
@@ -46,7 +46,8 @@ def objects(self):
     @classmethod
     def _create_copy_of_instance(cls, instance):
         defaults = {}
-        fields = instance._meta.concrete_fields
+        fields = [f for f in instance._meta.concrete_fields if not f.primary_key]
+
         if cls._clonable_model_fields:
             fields = [f for f in fields if f.name in cls._clonable_model_fields]
 
diff --git a/sample/migrations/0002_library.py b/sample/migrations/0002_library.py
new file mode 100644
--- /dev/null
+++ b/sample/migrations/0002_library.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2.7 on 2019-11-04 13:46
+
+from django.db import migrations, models
+import model_clone.mixins.clone
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('sample', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Library',
+            fields=[
+                ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+            ],
+            bases=(model_clone.mixins.clone.CloneMixin, models.Model),
+        ),
+    ]
diff --git a/sample/models.py b/sample/models.py
--- a/sample/models.py
+++ b/sample/models.py
@@ -1,3 +1,5 @@
+from uuid import uuid4
+
 from django.conf import settings
 from django.db import models
 
@@ -29,3 +31,7 @@ class Book(CloneMixin, models.Model):
 
     def __str__(self):
         return _(self.name)
+
+class Library(CloneMixin, models.Model):
+    id = models.UUIDField(primary_key=True, default=uuid4)
+    name = models.CharField(max_length=100)


Test patch:
diff --git a/sample/tests.py b/sample/tests.py
--- a/sample/tests.py
+++ b/sample/tests.py
@@ -1,3 +1,9 @@
 from django.test import TestCase
 
-# Create your tests here.
+from .models import Library
+
+class TestCloneMixin(TestCase):
+    def test_clone_with_custom_id(self):
+        base = Library.objects.create(name='First library')
+        clone = base.make_clone()
+        self.assertNotEqual(base.pk, clone.pk)