Python 如何使Django模型实例与另一个模型实例关联
我想将租金项下的金额增加到账目项下的金额。当用户在租金中键入金额时,应扣除或添加帐户中的金额,并应在支付时重置,或在未支付时保持不变Python 如何使Django模型实例与另一个模型实例关联,python,django,Python,Django,我想将租金项下的金额增加到账目项下的金额。当用户在租金中键入金额时,应扣除或添加帐户中的金额,并应在支付时重置,或在未支付时保持不变 class Account(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=250) number = models.PositiveIntegerField(help_text="Account number
class Account(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=250)
number = models.PositiveIntegerField(help_text="Account number", unique=True, blank=True, null=False)
currency = models.CharField(max_length=3, choices=ALLOWED_CURRENCIES)
creation_date = models.DateTimeField(auto_now_add=True)
amount = models.DecimalField(max_digits=MONEY_MAX_DIGITS, decimal_places=MONEY_DECIMAL_PLACES, help_text="Latest" "balance", default=0, blank=False, null=True)
class Rent(models.Model):
source = models.ForeignKey(Account, on_delete=models.CASCADE, verbose_name="Account holder.")
amount = models.DecimalField(max_digits=MONEY_MAX_DIGITS, decimal_places=MONEY_DECIMAL_PLACES)
date = models.DateTimeField(auto_now_add=True)
您可以使用以下三种策略之一:
amount
字段:
from django.db.models import Sum
class Account(models.Model):
# ...
def amount(self):
result = self.rent_set.all().aggregate(
total_amount=Sum('amount'))
return result['total_amount']
这种方法的优点是总是准确的:无论您如何创建和操作帐户和租金记录,这种方法都会返回正确的金额
它的缺点是每次调用时都会发出查询。这将对性能产生影响from django.db.models import Sum
class Account(models.Model):
# ...
def update_amount(self):
result = self.rent_set.all().aggregate(
total_amount=Sum('amount'))
self.amount = result['total_amount']
class Rent(models.Model):
# ...
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.account.update_amount()
self.account.save()
def delete(self, *args, **kwargs):
account = self.account
super().delete(*args, **kwargs)
account.update_amount()
account.save()
这种方法的优点是,金额存储在帐户记录中,因此不需要在每次需要时重新计算,只有在保存租金对象时才需要重新计算
缺点是必须对Rent对象调用save()
和delete()
。例如,您不能使用诸如Rent.objects.all().delete(…)
或Rent.objects.all().update(…)
之类的查询集方法,因为不会调用您的自定义save()
和delete()
另一个问题是,如果您在数据库级别编辑/删除租金记录,而不使用自定义代码,则金额将不会更新post\u delete
我建议使用信号(post_save)而不是覆盖租金节省方法。我认为更新将在不同的型号中进行,这特别干净。@user3375448:谢谢,非常好的建议!在第二个建议中,我是否为
账户
和总和
创建新实例?@tonde:您必须将更新金额
方法添加到现有的账户
类中。Django已经提供了Sum
类,只需从Django.db导入它:。models import Sum
。它回答了你的问题吗?
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
@receiver(post_save, sender=Rent)
@receiver(post_delete, sender=Rent)
def my_handler(sender, instance, **kwargs):
instance.account.update_amount()