Django сигнализирует о максимальной глубине рекурсии при обновлении поля модели

Я пытаюсь обновить поле статуса с помощью сигналов, но получаю ошибку максимальной рекурсии. Использую django 4.1.1.

models.py

class Product(models.Model):
  # ….
    PRODUCT_STATUS = (
        ('P', _('Preparation')),
        ('S', _('Sold')),
        ('T', _('Shipped')),
    )

    status = models.CharField(max_length=1, null=True,
                              choices=PRODUCT_STATUS, default='P')
    price_sold = models.DecimalField(
        _('Price Sold'), max_digits=10, decimal_places=2, blank=True, null=True)

#…

signals.py

@receiver(post_save, sender=Product)
def post_save_product_set_status_sold_if_price_sold(sender, instance, created, **kwargs):
    if instance.price_sold != None:
        instance.status = 'S'
        instance.save(update_fields=['status'])

Я получаю следующую ошибку при сохранении

RecursionError at /admin/products/product/14/change/ превышена максимальная глубина рекурсии при вызове объекта Python

Может кто-нибудь помочь?

Спасибо M

все понятно. По сигналу after_save Product вы вызываете save Product и это вызвало сигнал after_save Product и .... рекурсию.

в вашем случае:

def post_save_product_set_status_sold_if_price_sold(sender, instance, *args, **kwargs):
    if instance.price_sold != None:
        type(instance).objects.filter(pk=instance.pk).update(status = 'S')

Возможно, вам нужен pre-save сигнал. https://docs.djangoproject.com/en/4.1/ref/signals/#pre-save

Но я не понимаю, почему вы хотите сделать это с помощью сигнала. Вы можете:

  • проверьте его на form.clean() (лучший)
  • проверьте его на model.full_clean() (хорошо)
  • сделайте это на form.save() (нормально)
  • сделайте это на model.save() (слабый)
Вернуться на верх