Skip to content

Commit

Permalink
Add pre and post clone save signals (#680)
Browse files Browse the repository at this point in the history
* Add pre and post clone save signals

* Fix auto commit

* Fix assert annotations

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tonye Jack <[email protected]>
  • Loading branch information
3 people authored Nov 3, 2022
1 parent 8d14b87 commit 56342be
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 1 deletion.
6 changes: 5 additions & 1 deletion model_clone/mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.utils.text import slugify

from model_clone.apps import ModelCloneConfig
from model_clone.signals import post_clone_save, pre_clone_save
from model_clone.utils import (
clean_value,
context_mutable_attribute,
Expand Down Expand Up @@ -233,13 +234,16 @@ def make_clone(self, attrs=None, sub_clone=False, using=None, parent=None):

duplicate = self.pre_save_duplicate(duplicate)
duplicate = self.__duplicate_m2o_fields(duplicate, using=using)

pre_clone_save.send(sender=self.__class__, instance=duplicate)

duplicate.save(using=using)

duplicate = self.__duplicate_o2o_fields(duplicate, using=using)
duplicate = self.__duplicate_o2m_fields(duplicate, using=using)
duplicate = self.__duplicate_m2m_fields(duplicate, using=using)

duplicate.save(using=using)
post_clone_save.send(sender=self.__class__, instance=duplicate)

return duplicate

Expand Down
4 changes: 4 additions & 0 deletions model_clone/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.db.models.signals import ModelSignal

pre_clone_save = ModelSignal(use_caching=True)
post_clone_save = ModelSignal(use_caching=True)
38 changes: 38 additions & 0 deletions model_clone/tests/test_clone_signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.utils import timezone
from django.utils.text import slugify

from sample.models import Book, Edition

User = get_user_model()


class CloneSignalsTestCase(TestCase):
REPLICA_DB_ALIAS = "replica"
databases = {
"default",
"replica",
}

@classmethod
def setUpTestData(cls):
cls.user = User.objects.create(username="user")

def test_signals(self):
name = "New Book"
first_published_at = timezone.datetime(
1970, 1, 1, tzinfo=timezone.get_default_timezone()
)
book = Book.objects.create(
name=name,
created_by=self.user,
slug=slugify(name),
published_at=first_published_at,
)
self.assertEqual(book.published_at, first_published_at)
edition = Edition.objects.create(seq=1, book=book)
cloned_edition = edition.make_clone()
self.assertEqual(cloned_edition.seq, 2)
book.refresh_from_db()
self.assertNotEqual(book.published_at, first_published_at)
1 change: 1 addition & 0 deletions sample/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = "sample.apps.SampleConfig"
4 changes: 4 additions & 0 deletions sample/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# pylint: disable=unused-import
from django.apps import AppConfig


class SampleConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "sample"

def ready(self):
from . import signals # noqa: F401
18 changes: 18 additions & 0 deletions sample/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.dispatch import receiver
from django.utils import timezone

from model_clone.signals import post_clone_save, pre_clone_save

from .models import Edition


@receiver(pre_clone_save, sender=Edition)
def increase_seq(sender, instance, **kwargs):
instance.seq += 1


@receiver(post_clone_save, sender=Edition)
def update_book_published_at(sender, instance, **kwargs):
if instance.book:
instance.book.published_at = timezone.now()
instance.book.save(update_fields=["published_at"])

0 comments on commit 56342be

Please sign in to comment.