Django信号post_save方法

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

Django signals post_save method

问题

以下是翻译好的部分:

我正在使用django-rest-framework创建在线商店的API,但由于某种原因无法使我的post_save信号工作。我的想法是:我有一个模型ProductCategoryProduct模型有一个名为in_stock的字段,默认为True。至于Category模型,它也有一个in_stock字段,但这里是False。当创建产品实例时,我希望使用信号将Category字段的in_stock分配为True值。以下是模型的代码:

  1. class Category(models.Model):
  2. category_name = models.CharField(max_length=255, verbose_name='Категория')
  3. description = models.TextField(verbose_name='Описание')
  4. in_stock = models.BooleanField(default=False, verbose_name='В наличии')
  5. slug = models.SlugField()
  6. image_url = models.ImageField(upload_to='categories/uploads/%Y/%m/%d/', null=True, blank=True,
  7. default='media/images.png', verbose_name='Изображение')
  8. parent = models.ForeignKey('self', on_delete=models.PROTECT, related_name='children', null=True, blank=True,
  9. verbose_name='Родительская категория')
  10. def __str__(self):
  11. return f'{self.parent}, {self.category_name}'
  12. class Product(models.Model):
  13. product_name = models.CharField(max_length=255, verbose_name='Товар')
  14. description = models.TextField(verbose_name='Описание')
  15. price = models.IntegerField(verbose_name='Цена')
  16. discount_percent = models.IntegerField(default=0, verbose_name='Процент скидки')
  17. in_stock = models.BooleanField(default=True, verbose_name='В наличии')
  18. amount = models.IntegerField(verbose_name='Количество')
  19. vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE, verbose_name='Поставщик')
  20. category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='Категория')
  21. brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name='Бренд')
  22. image = models.ForeignKey(ProductImage, on_delete=models.SET_DEFAULT, default=1,
  23. verbose_name='Изображение')

以下是信号:

  1. @receiver(post_save, sender=Product)
  2. def update_category_is_active(sender, instance, created, **kwargs):
  3. print(instance)
  4. if created and instance.in_stock:
  5. instance.category.in_stock = True
  6. 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:

  1. class Category(models.Model):
  2. category_name = models.CharField(max_length=255, verbose_name='Категория')
  3. description = models.TextField(verbose_name='Описание')
  4. in_stock = models.BooleanField(default=False, verbose_name=&#39 наличии')
  5. slug = models.SlugField()
  6. image_url = models.ImageField(upload_to='categories/uploads/%Y/%m/%d/', null=True, blank=True,
  7. default='media/images.png', verbose_name='Изображение')
  8. parent = models.ForeignKey('self', on_delete=models.PROTECT, related_name='children', null=True, blank=True,
  9. verbose_name='Родительская категория')
  10. def __str__(self):
  11. return f'{self.parent}, {self.category_name}'
  12. class Product(models.Model):
  13. product_name = models.CharField(max_length=255, verbose_name='Товар')
  14. description = models.TextField(verbose_name='Описание')
  15. price = models.IntegerField(verbose_name='Цена')
  16. discount_percent = models.IntegerField(default=0, verbose_name='Процент скидки')
  17. in_stock = models.BooleanField(default=True, verbose_name=&#39 наличии')
  18. amount = models.IntegerField(verbose_name='Количество')
  19. vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE, verbose_name='Поставщик')
  20. category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='Категория')
  21. brand = models.ForeignKey(Brand, on_delete=models.CASCADE, verbose_name='Бренд')
  22. image = models.ForeignKey(ProductImage, on_delete=models.SET_DEFAULT, default=1,
  23. verbose_name='Изображение')

Here is signals:

  1. @receiver(post_save, sender=Product)
  2. def update_category_is_active(sender, instance, created, **kwargs):
  3. print(instance)
  4. if created and instance.in_stock:
  5. instance.category.in_stock = True
  6. instance.category.save()

答案1

得分: 1

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

英文:

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

  1. class Product(models.Model):
  2. ...
  3. def save(self, *args, **kwargs):
  4. if self.pk is None:
  5. if self.in_stock:
  6. self.category.in_stock = True
  7. self.category.save()
  8. super().save(*args, **kwargs)

答案2

得分: 0

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

  1. from django.apps import AppConfig
  2. class AppNameConfig(AppConfig):
  3. name = 'appname'
  4. def ready(self):
  5. 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:

  1. from django.apps import AppConfig
  2. class AppNameConfig(AppConfig):
  3. name = 'appname'
  4. def ready(self):
  5. 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:

确定