gpt4 book ai didi

python - Django 发出多对多变化的信号

转载 作者:太空宇宙 更新时间:2023-11-03 14:00:18 26 4
gpt4 key购买 nike

我有 3 个模型:

class Product(TimeStampedModel):
category = models.ForeignKey('Category', related_name='products', to_field='category_name')
brand = models.ForeignKey('Brand', related_name='products', to_field='brand_name')

class Brand(models.Model):
brand_name = models.CharField(max_length=50)
categories = models.ManyToManyField('Category', related_name='categories')

class Category(models.Model):
category_name = models.CharField(max_length=128)

我想在更改 Product.category 后更新 Brand-Category M2M 关系。
我尝试连接信号 m2m_changed,就像 docs 中描述的那样:

@receiver(m2m_changed, sender=Brand.categories.through)
def category_changed(sender, **kwargs):
print("Signal connected!")

此外,我还在 project_folderapps.py 中注册了一个 signal:

  def ready(self):
from my_app.signals import category_changed

但问题是 - 这段代码没有任何效果。我更改了 Product.category - 但没有看到任何打印品。 我应该如何修复它才能使其正常工作?

最佳答案

这是处理 Many2Many 字段变化的正确方法 Django Docs

from django.db.models.signals import m2m_changed

m2m_changed.connect(category_changed,sender=Brand.categories.through)

编辑: 我没有意识到 Chiefir 要求在 QuerySet update 方法上发出信号,为此我们不能使用内置的 m2m_changed 信号。正如 Ralf 在之前的回答中指出的那样,在更新时触发信号可能会导致性能问题,例如在收听 through 被保存的情况下。但是,恕我直言,有一种解决方案不会带来性能问题。

基本上,您可以覆盖查询集更新方法,以便在每次更新整个查询集时触发自定义信号。这只会在每次查询集更新时触发一次,您可以通过检查更新参数将其指定为仅在一个特定字段更新时触发。

信号现在发送正在更新的查询集和作为有效负载的值。请注意,在此代码中,信号是在类别更新之前发送的。要更改它,请将 super 输出保存为变量,分派(dispatch)信号并返回变量。

from django.dispatch import Signal, receiver

product_category_updated = Signal(providing_args=["queryset", "value"])


class ProductQuerySet(models.QuerySet):

def update(self, *args, **kwargs):
if 'category' in kwargs:
product_category_updated.send(sender=self.__class__, queryset=self, value=kwargs.get('category'))
return super(ProductQuerySet, self).update(*args, **kwargs)

class ProductManager(models.Manager):

def get_queryset(self, show_hidden=False):
return ProductQuerySet(self.model, using=self._db, hints=self._hints)

class Product(TimeStampedModel):
objects = ProductManager()

category = models.ForeignKey('Category', related_name='products', to_field='category_name', on_delete=models.deletion.CASCADE)
brand = models.ForeignKey('Brand', related_name='products', to_field='brand_name', on_delete=models.deletion.CASCADE)

class Brand(models.Model):
brand_name = models.CharField(max_length=50, unique=True)
categories = models.ManyToManyField('Category', related_name='categories')

class Category(models.Model):
category_name = models.CharField(max_length=128, unique=True)

@receiver(product_category_updated, sender=ProductQuerySet)
def category_changed(sender, **kwargs):
print("Signal connected!")

我必须通过在 ForeignKey 字段上添加 on_delete 属性并使 brand_name 和 category_name 唯一来调整代码以适应我的 Django 2.0.7 版本。

关于python - Django 发出多对多变化的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50120079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com