admin django. Add the total price in admin - python

hello I have to add a line or for example total_price = 123312 in admin
models.py
class Exit(models.Model):
description= models.CharField(max_length=50)
data_uscita = models.DateField('data uscita')
price = models.DecimalField(decimal_places=2, null=True,blank=True)
admin.py
class ExitAdmin(admin.ModelAdmin):
list_display =['description','price','total_exit']
def total_exit(self, request):
total = Exit.objects.all().aggregate(tot=Sum('price'))['tot']
return total
but is not ok because j have a columns with the total_exit that are repeated. I want total write only just once
I'm using Python 2.7.11

If what you need it's a function that returns the total of all outcomes (exits in your case), this is how the function goes:
from django.db.models import Sum
#other code you may need
def get_total(self, request):
return Exit.objects.aggregate(total=Sum('price'))
But, as you only got one price by outcome it doesn't make any sense to make a aggregate function because you should need multiple prices by outcome and a cost model perse.

Related

Django: how to sum up numbers in django

i want to calculate the total sales and display the total price, i dont know how to write the function to do this. I have tried writing a little function to do it in models.py but it working as expected. This is what i want, i have a model named UserCourse which stored all the purchased courses, now i want to calculate and sum up all the price of a single course that was sold.
models.py
class Course(models.Model):
course_title = models.CharField(max_length=10000)
slug = models.SlugField(unique=True)
price = models.IntegerField(default=0)
class UserCourse(models.Model):
user = models.ForeignKey(User , null = False , on_delete=models.CASCADE)
course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
and also how do i filter this models in views.py so i can display the total price of courses a particular creator have sold.
Try this approach using aggregate where you filter all UserCourse objects from a particular course, then run an aggregate on the price for that course:
my_course = Course.objects.first()
total_amount_sold = UserCourse.objects.filter(
course=my_course,
).aggregate(total_amount_sold=Sum("course__price"))["total_amount_sold"]
You can use the aggregate functionality in your view:
from django.db.models import Sum
price_total = UserCourse.objects.filter(
course__title="a title"
).aggregate(
aggregate_price = Sum("course__price")
)["aggregate_price"]
To break it down:
First we get filter all the UserCourse objects where the course has a title of "a title"
Then we aggregate them, finding the sum of the course prices for all those courses picked up by the filter
By naming a variable in our Sum expression, the queryset will now have a named value that we can get by the name ['aggregate_price'] and assign to price_total
Now you can pass price_total via context to use in your template.
You can specify other filters to get price totals for different querysets. So if your creator is the user field in your UserCourse model, you can repeat the process with user__username = "my_username" as the filter

Django querying data out of models and get sum of field

I'm just beginning with Django and have the following question:
I have set up a model looking like
class Automation_Apps(models.Model):
app_name = models.CharField(max_length=50)
app_description = models.TextField(blank=True)
view_function_name = models.CharField(max_length=50)
time_saver_min = models.IntegerField()
implementation_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.app_name
class Automation_Usage(models.Model):
used_app = models.ForeignKey(Automation_Apps, on_delete=models.CASCADE)
used_by_user = models.ForeignKey(User, on_delete=models.CASCADE)
used_on_date = models.DateTimeField(auto_now_add=True)
I would like to query it like:
Select Sum(time_saver_min)
from Automation_Apps, Automation_Usage
where Automation_Usage.used_app = Automation_Apps.app_name
The goal of this is the following:
Automation_App will have the Apps and a field, how much time will be saved by using this app
Automation_Usage will have the records, when a user is utilizing the app.
With my query I would like to pull how often the apps where used and how much time was saved by using it (which comes from the Automation_App).
I would like to do this in my view.
To get sum of time utilized over all apps by each user:
from django.db.models import Sum
Automation_Usage.objects.values('used_by_user').annotate(time=Sum('used_app__time_saver_min'))
To get number of users and sum of time utilized for each app:
from django.db.models import Sum, Count
Automation_Usage.objects.values('used_app').annotate(users=Count('used_by_user'), time=Sum('used_app__time_saver_min'))
You can use the Model Sum to Sum the value of your model.
Do it this way;
from django.db.models import Sum
Then
data = Model.objects.aggregate(Sum('time_saver_min'))['time_saver_min__sum'] print(data)
You can use annotate in Django ORM.
My solution:
Sum(time_saver_min) based on Automation_Usage.used_app = Automation_Apps.app_name
=> queryset = Automation_Usage.objects.values('used_app').annotate(Coalesce(Sum('used_app__time_saver_min'), Value(0)))
=> print(queryset['used_app__time_saver_min__sum'])

An issue making addition through models.py making a simple calculation

Hello guys im practicing on django by now developping a simple expense tracker for a main project expample: Buying a flippable car for X amount and adding all the other expenses to get a single total.
my operation is mainly done in my model.py
models.py
from django.db import models
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
amount = models.FloatField()
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.title
class Expenses(models.Model):
project = models.ForeignKey(Project, related_name='expenses', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
amount = models.FloatField()
def __str__(self):
return self.title
def get_total_project_amount(self):
return self.amount + self.project.amount
What i wanna do is adding the main project and all the expenses togheter, but im not using the proper way, when i render the resuld it renders like this:
main project: 50$
expenses added from a model form : 2(new)
expense: 13(new)
expense: 25(new)
the total is: 52
total: 63
total: 75
I wanna render the main project and all the expenses to get a single result, something like 50+2+13+25
total : 90$ total amount soent to fix the car.
Anyone that understand addition lojic help please and thank you
.
You can sum upt the expenses with:
class Project(models.Model):
# …
#property
def total_amount(self):
subtotal = self.expenses.aggregate(
subtotal=Sum('amount')
)['subtotal'] or 0
return self.amount + subtotal
You can thus determine the total cost for a Project object myproject with:
myproject.total_amount
this will thus sum up the amount plus the sum of all the related Expenses.
Note: normally a Django model is given a singular name, so Expense instead of Expenses.
Note: When you make calculations with money, it is better to use a DecimalField [Django-doc],
not a FloatField [Django-doc]. Floats can generate rounding errors when you perform calculations.
You can also use django-money [GitHub] to specify a MoneyField. This has also specifies a currency, and can convert money to a different
currency.

Django / Python - Querying calculated field

I have the below models, and want to run a calculation on a foreign key of allocation and then sum the amounts.
class Fundraising(models.Model):
#property
def amount_raised(self):
amount_raised = FundraisingDonation.objects.filter(
fundraising_event=self,
).aggregate(donationamount=Coalesce(Sum('donationamount'), 0.00))['donationamount']
return amount_raised
class FundraisingDonation(models.Model):
donationamount = models.DecimalField(max_digits=11, decimal_places=2, default=0)
class Testmodel(models.Model):
organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE)
allocation = models.ForeignKey(Fundraising, on_delete=models.CASCADE, related_name='items')
percentshare = models.DecimalField(max_digits=11, decimal_places=2, default=0) #SET BY USER
#property
def amount(self):
amount = self.allocation.amount_raised * self.percentshare
return amount
The 'amount' model property above calculates the amount field for each model instance.
I'm trying now to sum up the amounts for each organisation on a new model, however the following doesn't work as I don't believe I can run a query on a calculated field?
class Totals(models.Model):
totals = total + totalB + totalC
#property
def total(self):
total = Testmodel.objects.filter(
organisation=self.organisation
).aggregate(amount=Coalesce(Sum('amount'), 0.00))['amount']
Is there any way to amend the last line for this to work, or to reperform the calculation in this line? I also tried aggregate(Sum(amount_raised * percentshare)), but this didn't seem to work either?
You can not aggregate on a #property, since that property is unknown at the database side.
What you can do is .annotate(…) [Django-doc] the queryset of Organisations for example:
from django.db.models import F, Sum
Organisation.objects.annotate(
total=Sum(
F('testmodel__allocation__amount_raised') * F('testmodel__percentshare')
)
)
Each Organisation that arises from this queryset will have an extra attribute named .total that contains the sum of the amount_raised values for the related testmodel items, multiplied with percentshare.
EDIT: since the amount_raised is a property, we need to aggregate on the FundraisingDonation model, so:
from django.db.models import F, Sum, Value
from django.db.models.functions import Coalesce
Organisation.objects.annotate(
total=Coalesce(Sum(
F('testmodel__allocation__fundraising__donationamount') *
F('testmodel__percentshare'), Value(0))
)
)

Calculate a number in a Django model from another model's data

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 Usermodel 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
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')}
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()
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

Categories

Resources