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

Django如何在另一模型字段中使用外键字段的关联属性

报错原因

你直接在FiatTransaction的模型类定义层级写currency = debit_account.currency是错误的。Django模型定义阶段,debit_account只是一个ForeignKey字段类的实例,不是具体的模型记录对象,没有关联到实际的Account数据,自然取不到currency属性,这就是报错的核心原因。

正确实现方案

根据你是否需要将currency存储到数据库,可以选择两种实现方式:

方案1:动态属性取值(无需冗余存储)

如果不需要用currency做数据库查询、过滤,直接将其设为动态属性即可:

class FiatTransaction(models.Model):
    debit_account = models.ForeignKey('company.Account', on_delete=models.CASCADE, related_name='debit_account')
    credit_account = models.ForeignKey('company.Account', on_delete=models.CASCADE, related_name='credit_account')
    executed_on = models.DateTimeField(auto_now_add=True)
    amount = models.FloatField()
    is_processed = models.BooleanField(default=False)
    fee = models.FloatField()
    memo = models.CharField(max_length=250)

    # 新增动态属性
    @property
    def currency(self):
        return self.debit_account.currency

    def __str__(self):
        return F"Transferred {self.amount} from {self.debit_account} to {self.credit_account} at {self.executed_on}"

调用时直接访问实例的.currency属性就会自动从关联的借记账户取对应货币值,不需要额外存储到数据库。

方案2:数据库存储(适合需要用currency做查询的场景)

如果需要基于currency做过滤、统计、索引,就将其设为普通字段,重写save方法自动赋值:

class FiatTransaction(models.Model):
    debit_account = models.ForeignKey('company.Account', on_delete=models.CASCADE, related_name='debit_account')
    credit_account = models.ForeignKey('company.Account', on_delete=models.CASCADE, related_name='credit_account')
    executed_on = models.DateTimeField(auto_now_add=True)
    amount = models.FloatField()
    # 新增存储currency的字段,editable设为False禁止手动修改
    currency = models.ForeignKey(FiatCurrency, on_delete=models.CASCADE, editable=False)
    is_processed = models.BooleanField(default=False)
    fee = models.FloatField()
    memo = models.CharField(max_length=250)

    def save(self, *args, **kwargs):
        # 保存前自动赋值
        if not self.currency_id and self.debit_account_id:
            self.currency = self.debit_account.currency
        # 如果业务允许修改debit_account,可以加逻辑同步更新currency
        # if self.debit_account_id and self.currency != self.debit_account.currency:
        #     self.currency = self.debit_account.currency
        super().save(*args, **kwargs)

    def __str__(self):
        return F"Transferred {self.amount} from {self.debit_account} to {self.credit_account} at {self.executed_on}"

使用该方案需要执行makemigrations和migrate命令,将新增的currency字段同步到数据库表中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:36:08