Reputation: 3222
How do I get value of another class in the same model?
Can I also use properties?
I want to use Finance.net_income and Finance.net_margin inside the Stats Class. I tried searching for an anwser but I couldnt find it, I am also new to 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
Upvotes: 2
Views: 80
Reputation: 476557
Given you want to calculate the sum of the Finance
s with the same Stock
as the Stock
of the Stat
s object, you can calculate this with:
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
or a more descriptive filter:
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
If no all Stats
objects have one or more Finance
objects, then the Sum
will return None
(NULL
), in that case we probably want to return 0
instead. We can use the Coalesce
[Django-doc] function for this:
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
Upvotes: 1
Reputation: 51948
Try like this:
@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
Well, you will not get a single instance of Finance, because it is Foreign Key between Finance and Stock, meaning one stock can have multiple finance.
Upvotes: 3