From a36d36dae5359ae32d1a77e45c8ab3d87c8a20d1 Mon Sep 17 00:00:00 2001 From: Take Weiland Date: Mon, 17 May 2021 14:35:13 +0200 Subject: [PATCH 1/4] Add support for unique TextFields Fixes #331 --- model_clone/mixins/clone.py | 2 +- model_clone/tests/test_clone_mixin.py | 6 ++++++ model_clone/utils.py | 2 +- sample/migrations/0016_product.py | 20 ++++++++++++++++++++ sample/models.py | 5 +++++ 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 sample/migrations/0016_product.py diff --git a/model_clone/mixins/clone.py b/model_clone/mixins/clone.py index 8ab09d13..ab64d27e 100644 --- a/model_clone/mixins/clone.py +++ b/model_clone/mixins/clone.py @@ -325,7 +325,7 @@ def _create_copy_of_instance(instance, force=False, sub_clone=False): ] ): # Do not try to get unique value for enum type field - if isinstance(f, models.CharField) and not f.choices: + if isinstance(f, (models.CharField, models.TextField)) and not f.choices: value = clean_value(value, unique_duplicate_suffix) if use_unique_duplicate_suffix: value = get_unique_value( diff --git a/model_clone/tests/test_clone_mixin.py b/model_clone/tests/test_clone_mixin.py index 4ce69ef1..78a84596 100644 --- a/model_clone/tests/test_clone_mixin.py +++ b/model_clone/tests/test_clone_mixin.py @@ -25,6 +25,7 @@ BookSaleTag, Tag, SaleTag, + Product, ) User = get_user_model() @@ -649,3 +650,8 @@ def test_cloning_multiple_instances_with_autocommit_is_valid(self): clone.first_name, r"{}\s[\d]".format(Author.UNIQUE_DUPLICATE_SUFFIX), ) + + def test_cloning_model_with_unique_text_field(self): + product = Product.objects.create(name='Test Product') + clone = product.make_clone() + self.assertEqual(clone.name, f"{product.name} {Product.UNIQUE_DUPLICATE_SUFFIX} 1") diff --git a/model_clone/utils.py b/model_clone/utils.py index 0fad5476..64a1a855 100644 --- a/model_clone/utils.py +++ b/model_clone/utils.py @@ -162,7 +162,7 @@ def get_value(value, suffix, transform, max_length, index): duplicate_suffix = " {} {}".format(suffix, index) total_length = len(value + duplicate_suffix) - if total_length > max_length: + if max_length is not None and total_length > max_length: # Truncate the value to max_length - suffix length. value = value[: max_length - len(duplicate_suffix)] diff --git a/sample/migrations/0016_product.py b/sample/migrations/0016_product.py new file mode 100644 index 00000000..1160c1c0 --- /dev/null +++ b/sample/migrations/0016_product.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.3 on 2021-05-17 12:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sample', '0015_auto_20210423_0935'), + ] + + operations = [ + migrations.CreateModel( + name='Product', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField(unique=True)), + ], + ), + ] diff --git a/sample/models.py b/sample/models.py index 0e0b88e8..57f13e58 100644 --- a/sample/models.py +++ b/sample/models.py @@ -235,3 +235,8 @@ class Cover(CloneModel): class BackCover(models.Model): content = models.CharField(max_length=200) book = models.OneToOneField(Book, on_delete=models.CASCADE) + + +class Product(CloneMixin, models.Model): + name = models.TextField(unique=True) + From 7de2037bf8de2591851a0eab47f7d25bc71c9ee9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 12:36:36 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- model_clone/mixins/clone.py | 5 ++++- model_clone/tests/test_clone_mixin.py | 6 ++++-- sample/migrations/0016_product.py | 16 ++++++++++++---- sample/models.py | 1 - 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/model_clone/mixins/clone.py b/model_clone/mixins/clone.py index ab64d27e..d10306a7 100644 --- a/model_clone/mixins/clone.py +++ b/model_clone/mixins/clone.py @@ -325,7 +325,10 @@ def _create_copy_of_instance(instance, force=False, sub_clone=False): ] ): # Do not try to get unique value for enum type field - if isinstance(f, (models.CharField, models.TextField)) and not f.choices: + if ( + isinstance(f, (models.CharField, models.TextField)) + and not f.choices + ): value = clean_value(value, unique_duplicate_suffix) if use_unique_duplicate_suffix: value = get_unique_value( diff --git a/model_clone/tests/test_clone_mixin.py b/model_clone/tests/test_clone_mixin.py index 78a84596..0e163309 100644 --- a/model_clone/tests/test_clone_mixin.py +++ b/model_clone/tests/test_clone_mixin.py @@ -652,6 +652,8 @@ def test_cloning_multiple_instances_with_autocommit_is_valid(self): ) def test_cloning_model_with_unique_text_field(self): - product = Product.objects.create(name='Test Product') + product = Product.objects.create(name="Test Product") clone = product.make_clone() - self.assertEqual(clone.name, f"{product.name} {Product.UNIQUE_DUPLICATE_SUFFIX} 1") + self.assertEqual( + clone.name, f"{product.name} {Product.UNIQUE_DUPLICATE_SUFFIX} 1" + ) diff --git a/sample/migrations/0016_product.py b/sample/migrations/0016_product.py index 1160c1c0..8d069263 100644 --- a/sample/migrations/0016_product.py +++ b/sample/migrations/0016_product.py @@ -6,15 +6,23 @@ class Migration(migrations.Migration): dependencies = [ - ('sample', '0015_auto_20210423_0935'), + ("sample", "0015_auto_20210423_0935"), ] operations = [ migrations.CreateModel( - name='Product', + name="Product", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.TextField(unique=True)), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.TextField(unique=True)), ], ), ] diff --git a/sample/models.py b/sample/models.py index 57f13e58..ebcdd3ae 100644 --- a/sample/models.py +++ b/sample/models.py @@ -239,4 +239,3 @@ class BackCover(models.Model): class Product(CloneMixin, models.Model): name = models.TextField(unique=True) - From fb340916757bbe0a33d7ae7b7d6adac36e4db5ae Mon Sep 17 00:00:00 2001 From: Take Weiland Date: Mon, 17 May 2021 21:34:57 +0200 Subject: [PATCH 3/4] Use string format instead of f-strings for python 2 compat --- model_clone/tests/test_clone_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_clone/tests/test_clone_mixin.py b/model_clone/tests/test_clone_mixin.py index 0e163309..89f8b3fa 100644 --- a/model_clone/tests/test_clone_mixin.py +++ b/model_clone/tests/test_clone_mixin.py @@ -655,5 +655,5 @@ def test_cloning_model_with_unique_text_field(self): product = Product.objects.create(name="Test Product") clone = product.make_clone() self.assertEqual( - clone.name, f"{product.name} {Product.UNIQUE_DUPLICATE_SUFFIX} 1" + clone.name, "{0} {1} 1".format(product.name, Product.UNIQUE_DUPLICATE_SUFFIX) ) From 79d6971daf4c002eb88345924ea0032b0e6c306c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 19:35:09 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- model_clone/tests/test_clone_mixin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/model_clone/tests/test_clone_mixin.py b/model_clone/tests/test_clone_mixin.py index 89f8b3fa..c6bf3d51 100644 --- a/model_clone/tests/test_clone_mixin.py +++ b/model_clone/tests/test_clone_mixin.py @@ -655,5 +655,6 @@ def test_cloning_model_with_unique_text_field(self): product = Product.objects.create(name="Test Product") clone = product.make_clone() self.assertEqual( - clone.name, "{0} {1} 1".format(product.name, Product.UNIQUE_DUPLICATE_SUFFIX) + clone.name, + "{0} {1} 1".format(product.name, Product.UNIQUE_DUPLICATE_SUFFIX), )