Django 如何在更新另一个模型的基础上更新模型字段';s场使用信号?

Django 如何在更新另一个模型的基础上更新模型字段';s场使用信号?,django,signals,Django,Signals,我正在尝试添加交易模型中的所有总计值,并将它们放入销售模型的第一个实例(pk=1)总计字段。这是我的密码 型号.py class Sale(models.Model): gross_total = models.FloatField() def __unicode__(self): return str(self.gross_total) class Transaction(models.Model): sale = models.ForeignKey

我正在尝试添加
交易
模型中的所有
总计
值,并将它们放入
销售
模型的第一个实例(
pk=1
总计
字段。这是我的密码

型号.py

class Sale(models.Model):
    gross_total = models.FloatField()

    def __unicode__(self):
        return str(self.gross_total)

class Transaction(models.Model):
    sale = models.ForeignKey('Sale')
    price = models.FloatField()
    quantity = models.IntegerField()
    total = models.FloatField(blank=True, null=True)

    def save(self):
        self.total = self.price * self.quantity
        return super(Transaction, self).save()

    def __unicode__(self):
        return str(self.total)
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db.models import Sum

from .models import Transaction, Sale

@receiver(post_save, sender=Transaction)
def update_sale(sender, **kwargs):
    sale = Sale.objects.get(pk=1)
    sale.gross_total = Transaction.objects.all().aggregate(Sum('total'))['total__sum']
    sale.save()
default_app_config = 'alpha.apps.MyAppConfig'
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'alpha'
    verbose_name = 'Alpha'

    def ready(self):
        import alpha.signals
信号.py

class Sale(models.Model):
    gross_total = models.FloatField()

    def __unicode__(self):
        return str(self.gross_total)

class Transaction(models.Model):
    sale = models.ForeignKey('Sale')
    price = models.FloatField()
    quantity = models.IntegerField()
    total = models.FloatField(blank=True, null=True)

    def save(self):
        self.total = self.price * self.quantity
        return super(Transaction, self).save()

    def __unicode__(self):
        return str(self.total)
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db.models import Sum

from .models import Transaction, Sale

@receiver(post_save, sender=Transaction)
def update_sale(sender, **kwargs):
    sale = Sale.objects.get(pk=1)
    sale.gross_total = Transaction.objects.all().aggregate(Sum('total'))['total__sum']
    sale.save()
default_app_config = 'alpha.apps.MyAppConfig'
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'alpha'
    verbose_name = 'Alpha'

    def ready(self):
        import alpha.signals

我不熟悉使用Django信号。我做错了什么?如果我保存
交易
模型的实例,
销售
模型数据不会更新

我对我的应用程序进行了以下更改以使其正常工作

\uuuu init\uuuuu.py

class Sale(models.Model):
    gross_total = models.FloatField()

    def __unicode__(self):
        return str(self.gross_total)

class Transaction(models.Model):
    sale = models.ForeignKey('Sale')
    price = models.FloatField()
    quantity = models.IntegerField()
    total = models.FloatField(blank=True, null=True)

    def save(self):
        self.total = self.price * self.quantity
        return super(Transaction, self).save()

    def __unicode__(self):
        return str(self.total)
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db.models import Sum

from .models import Transaction, Sale

@receiver(post_save, sender=Transaction)
def update_sale(sender, **kwargs):
    sale = Sale.objects.get(pk=1)
    sale.gross_total = Transaction.objects.all().aggregate(Sum('total'))['total__sum']
    sale.save()
default_app_config = 'alpha.apps.MyAppConfig'
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'alpha'
    verbose_name = 'Alpha'

    def ready(self):
        import alpha.signals
现在在我的应用程序中创建apps.py

apps.py

class Sale(models.Model):
    gross_total = models.FloatField()

    def __unicode__(self):
        return str(self.gross_total)

class Transaction(models.Model):
    sale = models.ForeignKey('Sale')
    price = models.FloatField()
    quantity = models.IntegerField()
    total = models.FloatField(blank=True, null=True)

    def save(self):
        self.total = self.price * self.quantity
        return super(Transaction, self).save()

    def __unicode__(self):
        return str(self.total)
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db.models import Sum

from .models import Transaction, Sale

@receiver(post_save, sender=Transaction)
def update_sale(sender, **kwargs):
    sale = Sale.objects.get(pk=1)
    sale.gross_total = Transaction.objects.all().aggregate(Sum('total'))['total__sum']
    sale.save()
default_app_config = 'alpha.apps.MyAppConfig'
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'alpha'
    verbose_name = 'Alpha'

    def ready(self):
        import alpha.signals
我不知道这一切是如何运作的,哈哈。

发生的是

当您在
signals.py
中编写代码时,它是一个有效代码,但在直接执行(在本例中不是预期用途)或导入此模块之前,它永远不会运行。所以它必须被导入到某个地方,这样代码才能运行,处理函数才能注册到相应的信号中

运行Django项目时,Django会从
settings.py
中声明的应用程序创建应用程序注册表。创建注册表时,它将导入
settings.py
中声明的每个包和模块,并在此过程中调用几个预定义函数,包括每个
AppConfig
中的
ready()

在Python中导入包时,特殊文件
\uuuu init\uuuu.py
中的代码由Python内部自动执行,通常允许定义包的特殊行为和属性

因此,基本上,这导致:

  • Django项目启动

  • Django读取
    settings.py
    ,并将您的应用程序作为声明的应用程序之一查找

  • Django导入你的应用程序包,运行
    \uuuu init\uuuuuu.py
    中的代码,并指定
    default\u App\u config
    。现在德甘戈知道了

  • 当所有应用程序的处理完成后,Django会为前面步骤中找到的每个
    AppConfig
    调用
    ready()
    函数

  • 运行
    MyAppConfig
    中的
    ready()
    ,导入
    signals.py
    模块

  • 在此导入过程中,执行
    signals.py
    中的代码:创建
    update\u sale
    函数,并将其作为参数执行
    @receiver
    decorator

  • 正在执行的
    receiver
    decorator代码注册了
    update\u sale
    函数,该函数将在
    post\u save
    Transaction
    模型类发出的信号上运行


  • 您是否已将
    signals.py
    导入AppConfig中的
    ready()
    函数,如文档中“此代码应该存在于何处?”框中所建议的那样?@Nikita我没有这样做。我已经阅读了文档中的信号一章,但我不太清楚。在这方面你能帮忙吗?@Nikita好的,我从另一个博客复制代码时得到了这个,但我不知道它是如何工作的!你能给我推荐一本易读材料吗?不幸的是,我不知道易读材料,我同意Django文档的部分内容从清晰的解释到“我在读什么”:。然而,我试图解释一些额外的答案。