Django post_save preventing recursion without overriding model save()

前端 未结 9 1529
轻奢々
轻奢々 2020-11-29 23:41

There are many Stack Overflow posts about recursion using the post_save signal, to which the comments and answers are overwhelmingly: \"why not override save()\

相关标签:
9条回答
  • 2020-11-30 00:42

    Don't disconnect signals. If any new model of the same type is generated while the signal is disconnected the handler function won't be fired. Signals are global across Django and several requests can be running concurrently, making some fail while others run their post_save handler.

    0 讨论(0)
  • 2020-11-30 00:44

    You should use queryset.update() instead of Model.save() but you need to take care of something else:

    It's important to note that when you use it, if you want to use the new object you should get his object again, because it will not change the self object, for example:

    >>> MyModel.objects.create(pk=1, text='')
    >>> el = MyModel.objects.get(pk=1)
    >>> queryset.filter(pk=1).update(text='Updated')
    >>> print el.text
    >>> ''
    

    So, if you want to use the new object you should do again:

    >>> MyModel.objects.create(pk=1, text='')
    >>> el = MyModel.objects.get(pk=1)
    >>> queryset.filter(pk=1).update(text='Updated')
    >>> el = MyModel.objects.get(pk=1) # Do it again
    >>> print el.text
    >>> 'Updated'
    
    0 讨论(0)
  • 2020-11-30 00:46

    the Model's .objects.update() method bypasses the post_save signal

    Try this something like this:

    from django.db import models
    from django.db.models.signals import post_save
    
    
    class MyModel(models.Model):
    
        name = models.CharField(max_length=200)
        num_saves = models.PositiveSmallIntegerField(default=0)
    
        @classmethod
        def post_save(cls, sender, instance, created, *args, **kwargs):
            MyModel.objects.filter(id=instance.id).update(save_counter=instance.save_counter + 1)
    
    post_save.connect(MyModel.post_save, sender=MyModel)
    

    In this example, an object has a name and each time .save() is called, the .num_saves property is incremented, but without recursion.

    0 讨论(0)
提交回复
热议问题