Django:如何使用 pre_save 信号更新模型实例?
Posted
技术标签:
【中文标题】Django:如何使用 pre_save 信号更新模型实例?【英文标题】:Django: How to update model instance using pre_save signal? 【发布时间】:2019-08-17 23:55:29 【问题描述】:我想创建一个 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)
我想创建一个信号,该信号将在发送者模型或Sales
模型更新或删除之前的实例或创建新实例时更新Journal
实例。
知道如何执行此操作吗?
谢谢
【问题讨论】:
您正在向我们展示您的 pre_save 信号处理程序的代码。它不工作吗?或者它会引发错误?或者它做了一些意想不到的事情?解释你当前的代码在做什么。 它工作正常。我只是想为更新创建另一个 pre_save 信号,即当发送者被更新(未创建)时,它将更新它之前创建的日志模型的同一实例。否则它将删除以前的实例并创建一个新实例 这可能有助于***.com/a/10672822/6027876 【参考方案1】: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
、to
、credit
和debit
。
【讨论】:
不,问题仍然存在......它一直在创建一个新实例 是什么让Journal
实例对Sales
实例独一无二?根据什么获取现有的 Journal
实例?
有什么办法可以删除之前的条目并新建一个?
再次,您如何定义“上一个”条目?根据哪些参数,您知道要获取哪个条目?即哪个Journal
条目“属于”Sales
条目?为什么没有从 Journal 到 Sales 的 ForeignKey?
那么没有办法知道哪个Journal
条目是“上一个”条目。您需要在您的 Sales
对象上定义相应的 Journal
对象的一些唯一参数或参数组合。以上是关于Django:如何使用 pre_save 信号更新模型实例?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 pre_save 信号在 django 模型中保存相关对象
将pre_save信号更改为post_save?Django