简体   繁体   中英

Django: disconnect a post_save signal to avoid recursion

This is my model:

class Paper(models.Model):
    ...
    collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
    rang = models.IntegerField(default=0)
    class Meta:
        ordering = ['collection','rang']

When saving the model, I want it to update all the 'rang' fields in each object of the model so that they increase by 10.

I use the post_save signal below to avoid a problem of recursion:

@receiver(post_save, sender=Papier)
def redifine_rang(sender, *args,  **kwargs):
    for idx, paper in enumerate(Paper.objects.filter(collection = kwargs['instance'].collection)):
        paper.rang = idx*10
        Signal.disconnect(post_save, sender=Papier)
        paper.save()
        Signal.connect(post_save, sender=Papier)

However, I can't get the signal to disconnect and connect. Does anyone have any recommendations?

you can just use update

Paper.objects.filter(pk=paper.pk).update(rang=idx*10)

instead of

paper.rang = idx*10
Signal.disconnect(post_save, sender=Papier)
paper.save()
Signal.connect(post_save, sender=Papier)

A little clarification about the way to disable particular post_save signal. This way:

Signal.disconnect(post_save, sender=Papier)

is didn't work for Django 2.2.

The working option of turning off the signal will look like:

from django.db.models.signals import post_save
from django.dispatch import Signal


Signal.disconnect(post_save, receiver=redifine_range, sender=Papier)

It doesn't work for Django 4.0.

Now you need to disable a certain handler for the signal.

post_save.disconnect(your_handler, sender=Papier)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM