首页 > 解决方案 > Django:如何使用 pre_save 信号更新模型实例?

问题描述

我想创建一个 pre_save 信号,该信号将在发送者更新时更新已创建的模型实例。我想在 pre_save 信号中做到这一点。

模型的先前实例将被删除并创建新实例,或者将更新先前的实例。

我的模型:

class Sales(models.Model):
    user            = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    company         = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True)
    party_ac        = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='partyledgersales')
    sales           = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='saleledger')
    date            = models.DateField(default=datetime.date.today,blank=False, null=True)
    sub_total       = models.DecimalField(max_digits=10,decimal_places=2,blank=True, null=True)

class Journal(models.Model):
    user            = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    company         = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True,related_name='Companyname')
    voucher_id      = models.PositiveIntegerField(blank=True,null=True)
    date            = models.DateField(default=datetime.date.today)
    by              = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='Debitledgers')
    to              = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='Creditledgers')
    debit           = models.DecimalField(max_digits=10,decimal_places=2,null=True)
    credit          = models.DecimalField(max_digits=10,decimal_places=2,null=True)

我用于创建的 pre_save 信号:

@receiver(pre_save, sender=Sales)
def user_created_sales(sender,instance,*args,**kwargs):
    if instance.sub_total != None:
            Journal.objects.update_or_create(user=instance.user,company=instance.company,date=instance.date,voucher_id=instance.id,by=instance.party_ac,to=instance.sales,debit=instance.sub_total,credit=instance.sub_total)

我想创建一个信号,该信号将Journal在发送方模型或Sales模型更新或删除先前实例或创建新实例时更新实例。

知道如何执行此操作吗?

谢谢

标签: djangodjango-modelsdjango-signals

解决方案


update_or_create接受两组参数:

  • kwargs哪些是唯一标识要从数据库中获取的行的参数
  • defaults哪些是应该更新的参数

现在,您永远不会更新 的现有实例,Journal因为您没有指定defaults. 您正在寻找与所有参数匹配的实例,如果存在,则不执行任何操作,如果不存在,则创建它。

您还没有告诉我们是什么使Journal条目独一无二(以及它与Sales条目的关系,因为它们之间没有ForeignKey关系)。 更新:使用voucher_id,您现在可以查找相应的Journal条目。

但是像:

Journal.objects.update_or_create(
    user=instance.user,
    company=instance.company,
    voucher_id=instance.id,
    defaults={
        'date': instance.date,
        'debit': instance.sub_total,
        'credit': instance.sub_total,
        'by': instance.party_ac,
        'to': instance.sales}
)

将查找具有相同user,company和的现有实例,voucher_id并更新date, by,和.tocreditdebit


推荐阅读