Skip to content
Merged
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
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"])