how to sum all the consummations? - django

I already calculate, the total of one consummation, now i just want to sum all the consumations
class Consommation(models.Model):
food = models.ManyToManyField(Food)
consomme_le = models.DateTimeField(default=timezone.now, editable=False)
vipcustomer = models.ForeignKey(VipCustomer, models.CASCADE, null=True,
blank=True, verbose_name='Client prestigieux',
related_name='vip_consommations')
to calculate one consummation:
def total(self):
return self.food.aggregate(total=Sum('price'))['total']
Food class :
class Food(models.Model):
nom = models.CharField(max_length=100, verbose_name='Mon menu')
price = models.PositiveIntegerField(verbose_name='Prix')
category = models.ForeignKey(FoodCategory, models.CASCADE,
verbose_name="Categorie")
vipcustomer class:
class VipCustomer(models.Model):
first_name = models.CharField(max_length=150, verbose_name='Prénom')
last_name = models.CharField(max_length=100, verbose_name='Nom')
matricule = models.PositiveIntegerField(verbose_name='Matricule',
default=0)
adresse = models.CharField(max_length=200, verbose_name='Adresse',
blank=True)
telephone = PhoneField()
company = models.CharField(max_length=100, verbose_name='La société')
service = models.CharField(max_length=100, verbose_name='Service',
null=True, blank=True)
numero_badge = models.IntegerField(verbose_name='Numero du badge',
null=True, blank=True)
My goal is to calculate the total of all the consummations.

For a given VipCustomers, you can query with:
my_vip_customer.vip_consommations.aggregate(
total=Sum('food__price')
)['total']
We thus aggregate over the set of related Consommations, and we then aggregate over all the related Foods of these Consommations, and their corresponding price.
If there are no related Consommations, or no related Foods of these Consommations, then the sum will return None, instead of 0. We can add or 0 to convert a None to an 0 here:
my_vip_customer.vip_consommations.aggregate(
total=Sum('food__price')
)['total'] or 0
or for all Customers, we can annotate this with:
VipCustomer.objects.annotate(
total=Sum('vip_consommations__food__price')
)
Here the VipCustomers that arise from this, will have an extra attribute .total that contains the sum of the prices of the related Foods of the related Consommations.

Related

I am working on a django project that involves three models as indicated below Client,Loan,Payment

I am getting alot of duplicates in my template when i try to call the calculated loan payments in templates.
My models:
class Client(models.Model):
full_name = models.CharField(max_length=200,blank=True) staff=models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.SET_NULL,null=True,blank=True,related_name="client")
date = models.DateTimeField(default=timezone.now)
class Loan(models.Model):
ref = ShortUUIDField(length=6,max_length=6,alphabet="ABCDZXFQFHKRKL0123456789",unique=True)
loan_amount = models.IntegerField(blank=True,null=True)
staff=models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.SET_NULL,null=True,blank=True,related_name="loans")
search_client=models.ForeignKey(Client,on_delete=models.SET_NULL,null=True,blank=True)
#cached_property
def loan_repayments(self):
myfilter = Loan.objects.filter(ref=self.ref,payment__payment_reason='loan repayment')
result=myfilter.aggregate(total=Sum(F('payment__amount')))
total = result['total']
if total is None:
return 0
return total
class Payment(models.Model):
ref = ShortUUIDField(length=6,max_length=6,alphabet="ABCDZXFQFHKRKL0123456789",unique=True)
payment_reason = models.CharField(max_length=200, null=True, blank=True,choices=PAYMENT_REASON,default='loan repayment',db_index=True)
amount = models.IntegerField(blank=True, null=True)
lender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
blank=True, null=True, related_name="payments")
loan = models.ForeignKey(Loan, on_delete=models.CASCADE,
blank=True, null=True)
my view:
class Loan(LoginRequiredMixin,ListView):
query_set =Loan.objects.filter(status="active",action="creating loan").select_related('staff','search_client')
context_object_name = 'transactions'
paginate_by = 15
my template:
duplicates am getting:
duplicates in the toolbar

How to get difference between two annotate fields in django orm

The problem is that with this approach, annotate ignores equal amounts, and if you remove distinct=True, then there will be duplicate objects and the difference will not be correct.
In simple words, I want to get the balance of the account by getting the difference between the amount in cash and the amount on receipts for this personal account
queryset = PersonalAccount.objects.select_related(
'apartment', 'apartment__house', 'apartment__section', 'apartment__owner',
).annotate(
balance=
Greatest(Sum('cash_account__sum', filter=Q(cash_account__status=True), distinct=True), Decimal(0))
-
Greatest(Sum('receipt_account__sum', filter=Q(receipt_account__status=True), distinct=True), Decimal(0))
).order_by('-id')
class PersonalAccount(models.Model):
objects = None
class AccountStatus(models.TextChoices):
ACTIVE = 'active', _("Активен")
INACTIVE = 'inactive', _("Неактивен")
number = models.CharField(max_length=11, unique=True)
status = models.CharField(max_length=8, choices=AccountStatus.choices, default=AccountStatus.ACTIVE)
apartment = models.OneToOneField('Apartment', null=True, blank=True, on_delete=models.SET_NULL,
related_name='account_apartment')
class CashBox(models.Model):
objects = None
number = models.CharField(max_length=64, unique=True)
date = models.DateField(default=datetime.date.today)
status = models.BooleanField(default=True)
type = models.BooleanField(default=True)
sum = models.DecimalField(max_digits=10, decimal_places=2)
comment = models.TextField(blank=True)
payment_items = models.ForeignKey('PaymentItems', blank=True, null=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL, related_name='owner')
manager = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name='manager')
personal_account = models.ForeignKey('PersonalAccount', blank=True, null=True,
on_delete=models.SET_NULL, related_name='cash_account')
receipt = models.ForeignKey('Receipt', blank=True, null=True, on_delete=models.SET_NULL)
class Receipt(models.Model):
objects = None
class PayStatus(models.TextChoices):
PAID = 'paid', _("Оплачена")
PARTIALLY_PAID = 'partially_paid', _("Частично оплачена")
NOT_PAID = 'not_paid', _("Не оплачена")
number = models.CharField(max_length=64, unique=True)
date = models.DateField(default=datetime.date.today)
date_start = models.DateField(default=datetime.date.today)
date_end = models.DateField(default=datetime.date.today)
status = models.BooleanField(default=True)
status_pay = models.CharField(max_length=15, choices=PayStatus.choices, default=PayStatus.NOT_PAID)
sum = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, blank=True)
personal_account = models.ForeignKey('PersonalAccount', blank=True, null=True,
on_delete=models.CASCADE, related_name='receipt_account')
tariff = models.ForeignKey('Tariff', null=True, on_delete=models.CASCADE)
apartment = models.ForeignKey('Apartment', null=True, on_delete=models.CASCADE,
related_name='receipt_apartment')

Django Filter and Sum Value depends on different model

_Hi, guys! I'm trying to sum times for users for each Month(Mission), like this:
times = goal.time_set.filter(day__year=today.year, day__month=today.month)
Then I will sum:
for time in times:
total_min[member_number] = total_min[member_number] + time.value
But it calculates for current Month(Mission).
I want to calculate time depends on object model Mission. Model Mission:
class Mission(models.Model):
name = models.CharField(max_length=200, default='')
description = models.TextField(default='')
add_info = models.TextField(default='', blank=True)
theme = models.ImageField(upload_to='themes/', default='themes/default.png')
date_created = models.DateTimeField(null=True)
date_finished = models.DateTimeField(null=True, blank=True)
Like this I think:
times = goal.time_set.filter(day__year=mission.date_created.year, day__month=mission.month_created.month)
How can I achieve it?
upd. Goal model:
class Goal(models.Model):
STATUS = (
('in progress', 'in progress'),
('completed', 'completed'),
('failed', 'failed')
)
id_ninja = models.ForeignKey(Ninja, null=True, on_delete=models.SET_NULL)
id_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=150, default='')
description = models.TextField(default='')
date_created = models.DateTimeField(null=True)
status = models.CharField(max_length=20, choices=STATUS, default='in progress')
I solved the problem in my way.
mission_year = mission.date_created.strftime('%Y')
mission_month = mission.date_created.strftime('%m')
times = goal.time_set.filter(day__year__gte=mission_year, day__month__gte=mission_month)

Getting Count Result With Multiple Conditions

I have models named Class, StudentList, Child, TakingQuiz and TakingQuizAnswer. Students can take exams. In this case, when they start the exam, data is added to the 'TakingQuiz' table. With each new answer, the answers are also recorded in the TakingQuizAnswer table.
The result I want to reach -> The question with the most mistakes in the exams solved by the students in a class.
I tried to use Count for this. I'm filtering answer_is_correct to False but that is insufficient. I also need to filter this data for the question column. So I need to get rows where both question and answer_is_correct = False columns are the same and return the first few most repetitive data as results.
I always get a general result in my experiments. I can't include rows where the question column is the same. How can I access the questions with the most mistakes in exams solved by students studying in a class?
Serializer
class ClassSerializerReport(ModelSerializer):
instructor = InstructorSerializerReport(source="instructor.user")
students = StudenListSerializerReport(many=True,
source="student_list_class")
max_incorrect_question = serializers.SerializerMethodField()
class Meta:
model = Class
exclude = [
"created_at",
"updated_at",
"school",
]
def get_max_incorrect_question(self, obj):
data = Class.objects.filter(id = obj.id).values('student_list_class__child__child_taking_quiz__taking_quizes').annotate(res = Count('student_list_class__child__child_taking_quiz__taking_quizes__question', filter = Q(student_list_class__child__child_taking_quiz__taking_quizes__answer_is_correct = False)))
print(data)
return {"question_id" : "I couldn't access that result yet."}
Related Models
class Class(AbstractSchoolBaseModel):
school = models.ForeignKey(
"school.School",
on_delete=models.CASCADE,
related_name="classes_school",
)
instructor = models.ForeignKey(
"account.InstructorProfile",
on_delete=models.CASCADE,
related_name="instructors_school",
)
name = models.CharField(
max_length=50,
)
grade = models.IntegerField(
)
class StudentList(AbstractSchoolBaseModel):
school_class = models.ForeignKey(
"school.Class",
on_delete=models.CASCADE,
related_name="student_list_class",
)
child = models.ForeignKey(
"account.ChildProfile",
on_delete=models.CASCADE,
related_name="student_list_children",
)
class ChildProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
primary_key=True,
related_name="user_child")
city = models.ForeignKey(
"country.City",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="city_child_profiles")
hobbies = models.CharField(
max_length=500,
null=True,
blank=True,
)
class TakingQuiz(AbstractQuizBaseModel):
quiz = models.ForeignKey("quiz.Quiz", on_delete=models.DO_NOTHING, related_name="quiz_taking_quiz")
child = models.ForeignKey("account.ChildProfile", on_delete=models.CASCADE, related_name = "child_taking_quiz")
title = models.CharField(max_length=150, editable=False, default="-")
total_point = models.PositiveIntegerField(default=0)
class TakingQuizAnswer(AbstractQuizBaseModel):
taking_quiz = models.ForeignKey("quiz.TakingQuiz", on_delete=models.CASCADE, related_name="taking_quizes")
question = models.ForeignKey("quiz.Question", on_delete=models.DO_NOTHING, related_name="question_taking_quiz"e)
answer = models.ForeignKey("quiz.Answer", on_delete= models.DO_NOTHING, related_name="answer_taking_quiz")
taking_quiz_title = models.TextField(editable=False, null=True, blank=True)
question_text = models.TextField(editable=False, null=True, blank=True)
question_topic_content = models.TextField(editable=False, null=True, blank=True)
answer_text = models.TextField(editable=False, null=True, blank=True)
answer_is_correct = models.BooleanField(editable=False, null=True, blank=True)
class Quiz(AbstractQuizBaseModel):
ENABLED_CHOICES = (
(True, _("Active")),
(False, _("Not Active")),
)
book = models.ForeignKey("book.Book", on_delete= models.CASCADE, related_name="book_quiz")
title = models.CharField(max_length=150)
enabled = models.BooleanField(choices=ENABLED_CHOICES, default=False)
class Question(AbstractQuizBaseModel):
quiz = models.ForeignKey("quiz.Quiz", on_delete=models.DO_NOTHING, related_name="question_quiz")
question = models.CharField(max_length=500)
topic = models.CharField(max_length=500)
class Answer(AbstractQuizBaseModel):
IS_CORRECT_CHOICES = (
(True, _("Correct Answer")),
(False, _("Wrong Answer"))
)
question = models.ForeignKey("quiz.Question", on_delete=models.CASCADE, related_name = "question_answer")
answer = models.CharField(max_length=500)
is_correct = models.BooleanField(choices=IS_CORRECT_CHOICES, default=False)

Calculate the sum and multiply with the quantity to get the total in django

I have the code which calculates the sum just fine, now my question is it possible to multiple each price by quantity and then get the total sum after that in a cart on my website. I have tried with all of my logic but i have failed. The idea is to get the price of an item added to cart and multiply it by quantity and then get the total.
Here is my cart mode. models.py:
#cart model
class Cart(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
number_of_items = models.IntegerField(default=0)
user = models.ForeignKey(User, on_delete=models.CASCADE)
added_datetime = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.item.name
#Item model
class Item(models.Model):
CONDITION = (
('new', 'new'),
('used', 'used'),
('not applicable', 'not applicable'),
)
name = models.CharField(max_length=250)
owner = models.CharField(max_length=250, default='Ludocs-emark')
category = models.ForeignKey(ItemCategories, on_delete=models.CASCADE)
sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
Condition = models.CharField(max_length=250, null=True, choices=CONDITION)
price= models.IntegerField(default=0)
number_of_items = models.IntegerField(blank=True)
specification_one = models.CharField(max_length=250, blank=True)
specification_two = models.CharField(max_length=250, blank=True)
specification_three = models.CharField(max_length=250, blank=True)
specification_four = models.CharField(max_length=250, blank=True)
specification_five = models.CharField(max_length=250, blank=True)
specification_six = models.CharField(max_length=250, blank=True)
available_colors = models.CharField(max_length=250, blank=True)
description = RichTextField()
thumbnail = models.ImageField(default='default.png', upload_to='images/')
image_one = models.ImageField(upload_to='images/')
image_two = models.ImageField(upload_to='images/')
image_three = models.ImageField(upload_to='images/')
image_four = models.ImageField(upload_to='images/')
added_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
views.py file that i used to calculate the sum:
#This is the file where that i want to use to get the items added in cart and then multiply each by it's quantity and then get the total of the calculations when multiplied.
cart_sum = Cart.objects.filter(user=request.user).aggregate(Sum('item__price')).get('item__price__sum')
Yes, You can do that.
Try this
cart_sum = Cart.objects.filter(user=request.user).aggregate(Sum('item__price', field='item__price * number_of_items')).get('item__price__sum')
Assuming number_of_items as the quantity for the item from the Cart model.
Also you can return a total value so that if this gives any error for two different fields then you can do this
cart_sum = Cart.objects.filter(user=request.user).aggregate(total_price=Sum('item__price', field='item__price * number_of_items')).get('total_price')