Django - Signal.disconnect не отключает сигнал - PullRequest
1 голос
/ 19 марта 2019

Я не могу понять, почему сигнал 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()
...