【问题标题】:Get model attribute from other class in same model从同一模型中的其他类获取模型属性
【发布时间】:2018-11-30 11:27:41
【问题描述】:

如何获取同一模型中另一个类的值?
我也可以使用属性吗? 我想在 Stats 类中使用 Finance.net_income 和 Finance.net_margin。我尝试搜索 anwser 但我找不到它,我也是 django 的新手。

class Stats(models.Model):
    stock = models.ForeignKey(Stock, on_delete=models.CASCADE)
    shares_outstanding = models.FloatField(default=0)  

    @property
    def earnings_per_share(self):
        ####### ISSUE IS HERE #####
        return Finance.net_income / self.shares_outstanding

class Finance(models.Model):
    stock = models.ForeignKey(Stock, on_delete=models.CASCADE)
    total_revenue = models.FloatField(default=0) 
    operating_income = models.FloatField(default=0) 
    date = models.DateField(null=True, blank=True)
    net_income = models.FloatField(default=0) 
    cash = models.FloatField(default=0) 
    total_debt = models.FloatField(default=0) 

    @property
    def operating_margin(self):
        if self.total_revenue:
            now = (self.operating_income / self.total_revenue)*100
        else:
            now = 0
        return now

    @property
    def net_margin(self):
        if self.total_revenue:
            now = (self.net_income / self.total_revenue)*100
        else:
            now = 0
        return now

【问题讨论】:

  • 这里的Stats 对象与Finance 对象有什么关系?
  • property earnings_per_share 中,你需要得到模型Finance 的实例,一切都很好。
  • 两个类在同一个模型中
  • 那么我如何在其中获取实例?

标签: python django python-3.x django-models


【解决方案1】:

试试这样:

@property
def earnings_per_share(self):
   total_earnings_per_share = 0 
   for finance in self.stock.finance_set.all():
         total_earnings_per_share += finance.net_income / self.shares_outstanding
   return total_earnings_per_share

好吧,你不会得到一个 Finance 实例,因为它是 Finance 和 Stock 之间的外键,这意味着一只股票可以有多个 Finance。

【讨论】:

  • 完美,我如何获得最新的财务信息?按日期排序
  • 是的,使用order_by("-date")[0] :) 或者使用latest
【解决方案2】:

假设您想用与Stats 对象的Stock 相同的Stock 计算Finances 的总和,您可以使用以下方法计算:

from django.db.models import Sum

@property
def earnings_per_share(self):
    return Finance.objects.filter(
        stock_id=self.stock_id
    ).aggregate(
        total=Sum('net_income')
    )['total'] / self.shares_outstanding

或更具描述性的过滤器:

from django.db.models import Sum

@property
def earnings_per_share(self):
    return Finance.objects.filter(
        stock__stats=self
    ).aggregate(
        total=Sum('net_income')
    )['total'] / self.shares_outstanding

如果不是所有Stats 对象都有一个或多个Finance 对象,那么Sum 将返回None (NULL),在这种情况下我们可能希望返回0。我们可以为此使用Coalesce [Django-doc] 函数:

from django.db.models import Coalesce, Sum, Value

@property
def earnings_per_share(self):
    return Finance.objects.filter(
        stock__stats=self
    ).aggregate(
        total=Coalesce(Sum('net_income'), Value(0))
    )['total'] / self.shares_outstanding

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2013-06-06
    • 2014-12-10
    • 2015-04-12
    相关资源
    最近更新 更多