You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django DRF电商API中post_save信号失效问题求助

Django REST Framework post_save 信号失效问题

问题描述

我正在用Django REST Framework开发电商API,遇到post_save信号无法正常工作的问题。具体需求如下:

  • Product模型的in_stock字段默认值为True
  • Category模型的in_stock字段默认值为False
  • 创建Product实例时,通过信号将其关联的Category的in_stock字段设为True

模型代码

class Category(models.Model):
    category_name = models.CharField(max_length=255, verbose_name='Категория')
    description = models.TextField(verbose_name='Описание')
    in_stock = models.BooleanField(default=False, verbose_name='В наличии')
    slug = models.SlugField()
    image_url = models.ImageField(upload_to='categories/uploads/%Y/%m/%d/', null=True, blank=True,
                                  default='media/images.png', verbose_name='Изображение')

    parent = models.ForeignKey('self', on_delete=models.PROTECT, related_name='children', null=True, blank=True,
                               verbose_name='Родительская категория')

    def __str__(self):
        return f'{self.parent}, {self.category_name}'

class Product(models.Model):
    product_name = models.CharField(max_length=255, verbose_name='Товар')
    description = models.TextField(verbose_name='Описание')

    price = models.IntegerField(verbose_name='Цена')
    discount_percent = models.IntegerField(default=0, verbose_name='Процент скидки')

    in_stock = models.BooleanField(default=True, verbose_name='В наличии')
    amount = models.IntegerField(verbose_name='Количество')

    vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE, verbose_name='Поставщик')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='Категория')
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name='Бренд')
    image = models.ForeignKey(ProductImage, on_delete=models.SET_DEFAULT, default=1,
                              verbose_name='Изображение')

信号代码

@receiver(post_save, sender=Product)
def update_category_is_active(sender, instance, created, **kwargs):
    print(instance)

    if created and instance.in_stock:
        instance.category.in_stock = True
        instance.category.save()

排查方向

  • 确认信号注册:检查信号代码所在文件是否被Django正确加载,比如在apps.py的ready()方法中导入信号模块,或者在应用的__init__.py中导入
  • 验证分支触发:在if created and instance.in_stock:分支内添加日志打印,确认该分支是否被执行
  • 检查关联字段:确保创建Product时category字段已正确赋值,不存在null的情况
  • 事务影响:如果创建Product时使用了数据库事务,post_save信号可能在事务提交前触发,导致Category的修改未持久化,可改用post_commit信号,或确保事务提交后执行保存操作
  • 权限验证:检查API请求的用户是否具备修改Category模型的权限,避免因权限不足导致保存失败

内容的提问来源于stack exchange,提问作者Mihail Bury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:53:14