Reputation:
I have a best-practice question:
I have a model Score
which contains a value and a ForeignKey to another model. It's my aim to make it possible to call account.scores.total_score()
and it will return the sum of the values of all scores in the account.
class Score(models.Model):
value = models.IntegerField()
account = models.ForeignKey(Account, related_name='scores')
I was thinking about writing a ScoreManager
and ScoreQuerySet
to handle this access easily.
class ScoreQuerySet(models.QuerySet):
def total_score(self):
return self.aggregate(Sum('value'))
class ScoreManager(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return ScoreQuerySet(self.model, using=self._db)
class Score(models.Model):
value = models.IntegerField()
account = models.ForeignKey(Account, related_name='scores')
objects = ScoreManager()
This does only work if I call account.scores.all().total_score()
but not directly with account.scores.total_score()
. This doesn't work, because somehow my model does not register the new Manager and QuerySet on the relationship. But maybe this isn't the best practice, so I don't need to take time to fix this and should choose another way.
So what do you guys think about this? Should I create a total_score()
function in the Account
model?
Thanks for your help!
Upvotes: 1
Views: 584
Reputation: 12867
If you always need to calculate the total score associated with an account, why not add it as a method to your Account model?
class Account(models.Model): ...
def get_total_score(self):
return self.scores.aggregate(Sum('value'))
# or even as a property:
@property
def total_score(self):
return self.scores.aggregate(Sum('value'))
Upvotes: 1