You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中无外键关联时如何从一个模型访问另一个模型的属性

实现方案

首先你需要先明确两个模型的实例匹配规则(无外键的前提下必须有业务规则来确定你要关联的具体PiggyBank实例),以下是两种常见场景的实现方式:

场景1:计算全局总存款减去总取款得到余额

直接通过Django ORM的聚合方法统计PiggyBank的总存款、Withdrawal的总取款,计算当前余额:

from django.db.models import Sum
from decimal import Decimal

class Withdrawal(models.Model):
    date=models.DateField(default=None)
    particulars=models.CharField(max_length=200)
    amount=models.DecimalField(max_digits=10, decimal_places=2, default=0)
    balance=models.DecimalField(max_digits=10, decimal_places=2, default=0)
    voucher_number=models.IntegerField()

    def calculate_balance(self):
        # 统计所有存钱记录的总金额
        total_deposit = PiggyBank.objects.aggregate(total=Sum('amount'))['total'] or Decimal('0.00')
        # 统计当前取款记录之前的所有取款总金额,需要包含当前记录可以去掉exclude逻辑
        total_withdraw = Withdrawal.objects.exclude(pk=self.pk).aggregate(total=Sum('amount'))['total'] or Decimal('0.00')
        # 计算余额 = 总存款 - 总已取款 - 当前取款金额
        return total_deposit - total_withdraw - self.amount

    # 如果你需要保存时自动写入balance字段,重写save方法即可
    def save(self, *args, **kwargs):
        self.balance = self.calculate_balance()
        super().save(*args, **kwargs)

场景2:按业务规则匹配对应PiggyBank实例

比如按相同日期匹配,只需在查询时加过滤条件即可:

def calculate_balance(self):
    # 取和当前取款记录同日期的所有存款总金额
    total_deposit = PiggyBank.objects.filter(date=self.date).aggregate(total=Sum('amount'))['total'] or Decimal('0.00')
    # 取同日期下之前的取款总金额
    total_withdraw = Withdrawal.objects.filter(date=self.date).exclude(pk=self.pk).aggregate(total=Sum('amount'))['total'] or Decimal('0.00')
    return total_deposit - total_withdraw - self.amount

注意事项

  • 如果你需要匹配的是单个PiggyBank实例,只需把聚合逻辑换成get()查询即可,比如PiggyBank.objects.get(唯一匹配条件)
  • 无外键关联的情况下要确保匹配规则的唯一性,避免出现查询返回多个实例或找不到实例的报错

内容的提问来源于stack exchange,提问作者noob87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:36:02