Reputation: 2951
I want to take data (amount_spent
) from the field of each user and add those numbers up and display them in another field (total_revenue
) from a different model (RevenueInfo
).
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
from django import forms, views
# Create your models here.
#LoginInfo is being used, LoginForms in forms.py is
class LoginInfo(models.Model):
username = models.CharField('', max_length=10)
password = models.CharField('', max_length=15)
class ExtendedProfile(models.Model):
user = models.OneToOneField(User)
amount_spent = models.DecimalField(max_digits=6, decimal_places=2)
class RevenueInfo(models.Model):
total_amount_spent = models.DecimalField(max_digits=6, decimal_places=2, default=0)
total_revenue = models.ForeignKey(ExtendedProfile, null=True)
class Product(models.Model):
category = models.CharField(max_length=100)
name = models.CharField(max_length=100)
description = models.TextField()
#photo = models.ImageField()
price_CAD = models.DecimalField(max_digits=6, decimal_places=2)
quantity = models.DecimalField(max_digits=2, decimal_places=0, null=True)
How could I go about this? Would I iterate of each User
model and find User.amount_spent
then add that to RevenueInfo.total_revenue
? I'm not sure how to put that into code. Also I'm pretty sure I don't need both total_amount_spent
and total_revenue
but I feel like I need a ForeignKey
Upvotes: 0
Views: 2385
Reputation: 962
You could add a classmethod
to the ExtendedProfile
model to aggregate the amount_spent
value for each User (which bypasses the need for a separate RevenueInfo
model):
from django.db.models import Sum
class ExtendedProfile(models.Model):
....
@classmethod
def total_user_spend(cls):
return cls.objects.aggregate(total=Sum('amount_spent'))
Then you can get the total spend using ExtendedProfile.total_user_spend()
:
>>> ExtendedProfile.total_user_spend()
{'total': Decimal('1234.00')}
Upvotes: 1
Reputation: 10777
Avoid iterating over database entities in python (it can get really slow). Look into aggregation, it allows you to efficiently get sum (average, max, min, etc...) of values in a database:
>>> from django.db.models import Sum
>>> ExtendedProfile.objects.all().aggregate(Sum('amount_spent'))
{'amount_spent__sum': Decimal('1234.56')}
>>> # ... do whatever you want with the return value
Upvotes: 1
Reputation: 504
Yes, you can write a method for that in your model. There are 2 ways for it. 1) Writing a method that calculates the values and sets it to a instance value. 2) Writing a method that calculates the value and directly returns it.
For example purpose, here is the code for 2nd type.
# models.py
def total_amount_spent(self):
temp_values = [int(user.amount_spent) for user in ExtendedProfile.objects.all()]
return sum(temp_values)
And for using that value in views , but remeber it would be an integer by default
#views.py
value = RevenueInfo.total_amount_spent()
Upvotes: 1