diff --git a/design_builder/contrib/ext.py b/design_builder/contrib/ext.py index 5ddb6f4a..4cf7e8c2 100644 --- a/design_builder/contrib/ext.py +++ b/design_builder/contrib/ext.py @@ -11,7 +11,7 @@ from nautobot.ipam.models import Prefix import netaddr -from design_builder.design import INSTANCE_POST_SAVE, Builder +from design_builder.design import Builder from design_builder.design import ModelInstance from design_builder.errors import DesignImplementationError @@ -384,9 +384,13 @@ def __init__(self, object_creator: Builder): ) @staticmethod - def _post_save(model_instance: ModelInstance, **kwargs) -> None: - endpoint_a = model_instance.instance.endpoint_a - endpoint_z = model_instance.instance.endpoint_z + def _post_save(sender, **kwargs) -> None: + from django.dispatch.dispatcher import _make_id + + print("SENDER", type(sender.instance), "ID", _make_id(sender), _make_id(BGPPeeringExtension._post_save)) + peering_instance: ModelInstance = sender + endpoint_a = peering_instance.instance.endpoint_a + endpoint_z = peering_instance.instance.endpoint_z endpoint_a.peer, endpoint_z.peer = endpoint_z, endpoint_a endpoint_a.save() endpoint_z.save() @@ -461,5 +465,14 @@ def attribute(self, value, model_instance) -> None: retval["endpoints"] = [endpoint_a, endpoint_z] endpoint_a.attributes["peering"] = model_instance endpoint_z.attributes["peering"] = model_instance - model_instance.connect(INSTANCE_POST_SAVE, BGPPeeringExtension._post_save) + from django.dispatch.dispatcher import _make_id + + print( + "Connecting to", + type(model_instance.instance), + "ID", + _make_id(model_instance), + _make_id(BGPPeeringExtension._post_save), + ) + model_instance.connect(ModelInstance.POST_SAVE, BGPPeeringExtension._post_save) return retval diff --git a/design_builder/design.py b/design_builder/design.py index d1dcbc6d..04e9ee0e 100644 --- a/design_builder/design.py +++ b/design_builder/design.py @@ -98,11 +98,6 @@ def _map_query_values(query: Mapping) -> Mapping: return retval -# Callback Event types -INSTANCE_PRE_SAVE = Signal() -INSTANCE_POST_SAVE = Signal() - - class ModelInstance: # pylint: disable=too-many-instance-attributes """An individual object to be created or updated as Design Builder iterates through a rendered design YAML file.""" @@ -114,6 +109,10 @@ class ModelInstance: # pylint: disable=too-many-instance-attributes ACTION_CHOICES = [GET, CREATE, UPDATE, CREATE_OR_UPDATE] + # Callback Event types + PRE_SAVE = Signal() + POST_SAVE = Signal() + def __init__( self, creator: "Builder", model_class: Type[BaseModel], attributes: dict, relationship_manager=None, parent=None ): # pylint:disable=too-many-arguments @@ -233,7 +232,13 @@ def connect(self, signal: Signal, handler): signal: Signal to listen for. handler: Callback function """ - signal.connect(handler, self.instance.pk) + dispatch_id = ( + self.model_class._meta.app_label, + self.model_class._meta.model_name, + id(handler), + ) + + signal.connect(handler, self, dispatch_uid=dispatch_id) def _load_instance(self): query_filter = _map_query_values(self.filter) @@ -310,7 +315,7 @@ def save(self): # ensure that parent instances have been saved and # assigned a primary key self._update_fields() - INSTANCE_PRE_SAVE.send(sender=self.instance.pk, model_instance=self) + ModelInstance.PRE_SAVE.send(sender=self) try: self.instance.full_clean() self.instance.save() @@ -339,7 +344,7 @@ def save(self): self.instance.refresh_from_db() field.set_value(related_object.instance) - INSTANCE_POST_SAVE.send(sender=self.instance.pk, model_instance=self) + ModelInstance.POST_SAVE.send(sender=self) def set_custom_field(self, field, value): """Sets a value for a custom field."""