@bituke

Как вызвать функцию модели, используя другую модель?

Добрый день, есть модель tickervalue с функцией, которую нужно вызвать с другой модели:

class TickerValue(models.Model):
	ticker = models.ForeignKey(Ticker, on_delete=models.CASCADE, related_name='ticker_value')
	date = models.DateField()
	closing_cost = models.FloatField()

	def get_total_value(self, client):
		today = datetime.now()
		today = datetime.strftime(today, '%Y-%m-%d')
		yesterday = datetime.now() - timedelta(1)
		yesterday = datetime.strftime(yesterday, '%Y-%m-%d')
		last_objects = self.filter(ticker__ticker__portfolio__client=client, date__range=[yesterday, today])
		value = 0
		for i in last_objects.closing_cost:
			value += i
		return value


Модель, с которой я пытаюсь вызвать функцию:
class Client(models.Model):
	investmen = models.ForeignKey(InvestmentAdvisor, on_delete=models.CASCADE, related_name='client')
	name = models.CharField(max_length=255)

	def get_total_value(self):
		tickervalue = self.portfolio.stock.ticker.ticker_value.get_total_value(self)
		return tickervalue

Я пытаюсь вызвать эту функцию по связям моделей, но у меня не выходит это сделать, ибо 'RelatedManager' object has no attribute 'stock'.
Заранее благодарен за любую помощь.

Полный код:
models.py
class Client(models.Model):
	investmen = models.ForeignKey(InvestmentAdvisor, on_delete=models.CASCADE, related_name='client')
	name = models.CharField(max_length=255)
	description = models.TextField(blank=True)
	date_of_birth = models.DateField()
	retirement_date = models.DateField()
	drawdown_behavior = models.PositiveSmallIntegerField(choices=DRAWDOWN_BEHAVIOR,)
	employment_status = models.PositiveSmallIntegerField(choices=EMPLOYMENT_STATUS,)

	def get_total_value(self):
		tickervalue = self.portfolio.stock.ticker.ticker_value.get_total_value(self)
		return tickervalue



	def __str__(self):
		return self.name

class Portfolio(models.Model):
	client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='portfolio')
	name = models.CharField('название', max_length=255)
	initial_investment_amount = models.PositiveIntegerField('начальная сумма инвестиций',)
	investment_horizon = models.PositiveIntegerField('инвестиционный горизонт',)
	type_investor = models.PositiveSmallIntegerField('тип инвестора', choices=TYPE_INVESTOR)
	currency = models.PositiveSmallIntegerField('валюта', choices=CURRENCY)
	maximum_allowable_drawdown = models.PositiveIntegerField('максимально допустимая просадка',)
	type_according_risk_reward = models.PositiveSmallIntegerField('тип по соотношению риска/прибыли', choices=TYPE_RISK)
	focus = models.PositiveSmallIntegerField('фокус', choices=FOCUS)
	sector_blacklist = models.TextField(blank=True) 
	types_assets = models.TextField()
	ETF = models.PositiveSmallIntegerField(choices=ETF)
	investment_strategy = models.PositiveSmallIntegerField('инвестиционная стратегия', choices=INVESTMENT_STRATEGY)
	create_date = models.DateField(auto_now=True)
	active = models.BooleanField()

	def get_all_active(self):
		all_acive = self.objects.filter()


	def __str__(self):
		return self.name

	def get_type_investor(self):
		return TYPE_INVESTOR[self.type_investor][1]

	def get_focus(self):
		return FOCUS[self.focus][1]

	def get_investment_strategy(self):
		return INVESTMENT_STRATEGY[self.investment_strategy][1]

class Sector(models.Model):
	pass

class Ticker(models.Model):
	name = models.CharField(max_length=255)

	def __str__(self):
		return self.name

class TickerValue(models.Model):
	ticker = models.ForeignKey(Ticker, on_delete=models.CASCADE, related_name='ticker_value')
	date = models.DateField()
	closing_cost = models.FloatField()

	def get_total_value(self, client):
		today = datetime.now()
		today = datetime.strftime(today, '%Y-%m-%d')
		yesterday = datetime.now() - timedelta(1)
		yesterday = datetime.strftime(yesterday, '%Y-%m-%d')
		last_objects = self.filter(ticker__ticker__portfolio__client=client, date__range=[yesterday, today])
		value = 0
		for i in last_objects.closing_cost:
			value += i
		return value


	def __str__(self):
		return self.ticker.name


class Stock(models.Model):
	portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, related_name='stock')
	name = models.CharField(max_length=255, blank=True)
	ticker = models.ForeignKey(Ticker, on_delete=models.CASCADE, related_name='ticker')
	sector = models.CharField(max_length=255, blank=True)
	share = models.FloatField()

	def __str__(self):
		return self.ticker.name
  • Вопрос задан
  • 91 просмотр
Решения вопроса 1
@MEDIOFF
Python Developer
Вы явно делаете что то не так, когда пытаетесь вызвать функцию через 3 связи Client -> Portfolio -> TickerValue -> get_total_value()

Это о вопросе где писать реализацию, я вижу у вас два варианта как это сделать по человечески, либо вынести нужный функционал в Client (что не есть хорошо, ибо я придерживаюсь мнения что методы в моделях, должны взаимодействовать только с самой моделью, не задевая другие), либо, что для меня кажется более приемлемым, выносить данный функционал в отдельную функцию, и в своих вьюшках вызывать ее.
P.S

Вот вам если что для чтения материал по структуре и организации проекта на Django, там рассказано про сервисы, и почему их стоит выносить отдельно
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы