Django信号post_save方法

huangapple go评论71阅读模式
英文:

Django signals post_save method

问题

以下是翻译好的部分:

我正在使用django-rest-framework创建在线商店的API,但由于某种原因无法使我的post_save信号工作。我的想法是:我有一个模型ProductCategoryProduct模型有一个名为in_stock的字段,默认为True。至于Category模型,它也有一个in_stock字段,但这里是False。当创建产品实例时,我希望使用信号将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()
英文:

I am creating API for online-store with django-rest-framework and can't get my post_save signal working for some reason. The idea is: I have a model Product and Category. Product model has a field named in_stock, which is True by default. As for model Category, it also has field in_stock, but here it is False. When the product instance created, I want assign Category field in_stock to True value using singals. Here is the code of models:

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='Изображение')

Here is signals:

@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()

答案1

得分: 1

你可以通过重写save()方法来在没有信号的情况下获取它。

英文:

You can get it without signals by overriding save() method

class Product(models.Model):
    ...

    def save(self, *args, **kwargs):
        if self.pk is None:
            if self.in_stock:
                self.category.in_stock = True
                self.category.save()
        super().save(*args, **kwargs)

答案2

得分: 0

你是否在 apps.py 文件中添加了一个 ready 函数?这是必需的,因为 Django 需要知道哪些文件具有额外的代码(如 pre_save / post_save 等),在服务器运行时应该执行。它会类似于这样:

from django.apps import AppConfig

class AppNameConfig(AppConfig):
    name = 'appname'

    def ready(self):
        import appname.signals
英文:

Did you add a ready function in the apps.py file? This is required as Django should know which files have additional code(like pre_save/ post_save) which should be executed when the server is running.
It will look like something like this:

from django.apps import AppConfig

class AppNameConfig(AppConfig):
    name = 'appname'

    def ready(self):
        import appname.signals

huangapple
  • 本文由 发表于 2023年6月18日 17:55:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76499946.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定