[英]Can I perform queries in django pre_save signals?
這是models.py
class ledger1(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='Companys')
Creation_Date = models.DateField(default=datetime.now)
name = models.CharField(max_length=32,unique=True)
Opening_Balance = models.DecimalField(max_digits=19,decimal_places=2)
Closing_balance = models.DecimalField(max_digits=10,decimal_places=2)
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')
Date = models.DateField()
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,)
Credit = models.DecimalField(max_digits=10,decimal_places=2)
我想使用Django查詢建立數學方程式,方程式的結果將顯示在ledger1.Closing_Balance字段中
所以我嘗試了這個:
@receiver(pre_save, sender=ledger1)
def update_user_closing_balance(sender,instance,*args,**kwargs):
Closing_balance = ledger1.objects.annotate(debitsum=Sum('Debitledgers__Debit')) + instance.Opening_Balance - ledger1.objects.annotate(creditsum=Sum('Creditledgers__Credit'))
instance.Closing_balance = Closing_balance
在Django有可能嗎??? 因為如果我運行此命令,將會收到不受支持的操作數錯誤...
是否有其他替代代碼???
如果有人知道...請幫助
先感謝您
不支持的操作數異常與查詢本身無關,但與您編寫的表達式無關:
Closing_balance = (
ledger1.objects.annotate(debitsum=Sum('Debitledgers__Debit')) +
instance.Opening_Balance -
ledger1.objects.annotate(creditsum=Sum('Creditledgers__Credit'))
)
所以在這里您將QuerySet
與實際值一起添加,這沒有任何意義。 您可能想使用的是.aggregate(..)
,然后將其中包含的值包裝起來,例如:
debitsum = ledger1.objects.aggregate(debitsum=Sum('Debitledgers__Debit'))['debitsum']
creditsum = ledger1.objects.aggregate(creditsum=Sum('Creditledgers__Credit'))['creditsum']
Closing_balance = debitsum + instance.Opening_Balance - creditsum
話雖這么說,使用信號預先計算聚合通常不是一個好主意。 例如,由於journal
對象可以更改其Debit
或Credit
值,並且這不會“觸發”信號,因此不會進行任何更新。 即使您還為此類事件添加邏輯,信號仍然可能發生,因為例如批量更新將超過信號系統。
通常最好不要存儲數據聚合,因為這會導致數據重復 ,就像文章所說的那樣“ 滋生了冗余和不一致 ”。 如果要計算此類聚合,最好在數據庫級別使用(實例化)視圖。
編輯 :但是查詢本身似乎沒有任何意義。 如果更新ledger
記錄,則可以執行過濾,並通過以下方式計算更新:
@receiver(pre_save, sender=ledger1)
def update_user_closing_balance(sender,instance,*args,**kwargs):
debit = instance.Debitledgers.aggregate(debit=Sum('Debit'))['debit']
credit = instance.Creditledgers.aggregate(credit=Sum('Credit'))['credit']
instance.Closing_balance = instance.Opening_Balance + debit - credit
但這可能仍不足夠,因為您隨后需要對日期進行一些適當的過濾,等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.