Я не могу понять, почему сигнал disconnect
из post_save
не работает в моем проекте.
Когда я вызываю PipedriveSync.objects.first().sync_with_pipedrive()
, он что-то делает, а затем пытается сохранить некоторую информацию для объекта.Затем вызывается приемник sync_pipedrivesync
, который снова вызывает sync_with_pipedrive()
, который вызывает sync_pipedrivesync
и т. Д. И т. Д.
Чтобы избежать этой цикличности, я создал два метода - disconnect_sync
и connect_sync
, которые должны отключатьсясигнал при сохранении экземпляра, а затем отозвать его.Но это не работает.
Я вижу в отладчике, что последняя строка в sync_with_pipedrive
- self.save(disconnect=True)
вызывает сигнал.
Знаете ли вы, что не так?
models.py
class PipedriveSync(TimeStampedModel):
pipedrive_id = models.IntegerField(null=True, blank=True)
last_sync = models.DateTimeField(null=True, blank=True)
last_sync_response = JSONField(null=True, blank=True)
last_sync_success = models.NullBooleanField()
last_backsync = models.DateTimeField(null=True, blank=True)
last_backsync_response = JSONField(null=True, blank=True)
last_backsync_success = models.NullBooleanField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
def save(self,disconnect=True,**kwargs):
if disconnect:
PipedriveSync.disconnect_sync()
super().save(**kwargs)
PipedriveSync.connect_sync()
@classmethod
def disconnect_sync(cls):
post_save.disconnect(sync_pipedrivesync)
@classmethod
def connect_sync(cls):
post_save.connect(sync_pipedrivesync,sender=PipedriveSync)
def sync_with_pipedrive(self):
if self.pipedrive_id:
action = 'update'
else:
action = 'create'
relative_url = self.build_endpoint_relative_url(action)
payload = self.get_serializer_class()(self.content_object).data
response = None
if action == 'create':
response = PipeDriveWrapper.post(relative_url, payload=payload)
if response['success']:
self.pipedrive_id = response['data']['id']
if action == 'update':
response = PipeDriveWrapper.put(relative_url, payload=payload)
try:
success = response['success']
except KeyError:
success = False
self.last_sync_success = success
self.last_sync_response = response
self.last_sync = now()
self.save(disconnect=True)
@receiver(post_save, sender=PipedriveSync)
def sync_pipedrivesync(instance, sender, created, **kwargs):
instance.sync_with_pipedrive()