I have a model named 'CarAdd', and two other models are connected with a foreign key to this CarAdd model that are ShippingDetails, MaintenanceDetails. and each foreign key model has an item and price field." foreign key have more than 2 items under one id"
I need to find the profit amount of each car
profit = sold_amount - (purchased amount + total shipping cost + total maintenance cost)
class CarAdd(models.Model):
# Car Details
name = models.CharField(max_length=60)
purchased_amount = models.DecimalField()
# there 3 choices in STATUS shipped, maintenance, sold
status = models.CharField(max_length=12, choices=STATUS)
sold_amount = models.DecimalField(max_digits=15, decimal_places=1)
profit_amount = models.DecimalField(max_digits=15, decimal_places=1)
def save(self, *args, **kwargs):
if self.status == 'sold':
sum_invested = self.purchased_amount + ShippingDetails.price + MaintenanceDetails.price
profit = self.sold_amount - sum_invested
self.profit_amount = profit
super().save(*args, **kwargs)
class ShippingDetails(models.Model):
car = models.ForeignKey(CarAdd, related_name='shipping_details', on_delete=models.CASCADE)
item = models.CharField(max_length=60)
price = models.DecimalField(max_digits=15, decimal_places=1,)
class MaintenanceDetails(models.Model):
car = models.ForeignKey(CarAdd, related_name='maintenance_details', on_delete=models.CASCADE)
item = models.CharField(max_length=60)
price = models.DecimalField(max_digits=15, decimal_places=1)
how do I calculate the profit amount if status is 'sold' and save to profit_amount field
You need to aggregate on the related models:
from django.db.models import Sum
from django.db.models.functions import Coalesce
sum_invested = self.purchased_amount
+ self.shipping_details.aggregate(total_price=Coalesce(Sum('price'), 0))['total_price']
+ self.maintenance_details.aggregate(total_price=Coalesce(Sum('price'), 0))['total_price']
Related
I have created two models with two fields which are quantity and quantity_given, so I want to change the value of quantity field by adding the value of quantity + quantity given. For example
if quantity = 4 and quantity_given = 8
therefore the new value of quantity field will be 12.
Here are the source code for my models
class Stock(models.Model):
`name = models.CharField(max_length=30)`
def __str__(self):
return self.name
class Medicine(models.Model):
stock = models.ForeignKey(Stock, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
quantity = models.IntegerField()
def __str__(self):
return self.name
class MedicineGiven(models.Model):
medicine = models.ForeignKey(Medicine, on_delete=models.CASCADE)
quantity_given = models.IntegerField()
You can have a method in MedicineGiven, like:
class MedicineGiven(models.Model):
medicine = models.ForeignKey(Medicine, on_delete=models.CASCADE)
quantity_given = models.IntegerField()
#property
def quantity(self):
return self.quantity_given + int(self.medicine.quantity)
In your views, you can get quantity of MedicineGiven like:
medicine_given = MedicineGiven.objects.get(pk=id) # Just a example code
medicine_given.quantity
EDIT
If you want to save the quantity in database, then you can override save() method:
class MedicineGiven(models.Model):
medicine = models.ForeignKey(Medicine, on_delete=models.CASCADE)
quantity_given = models.IntegerField()
def save(self, *args, **kwargs):
quantity = self.quantity_given + int(self.medicine.quantity)
self.medicine.quantity = quantity
self.medicine.save()
super().save(*args, **kwargs)
I am new to Django. My query is
I store some quantity of components in a table. I want to sum the quantity sorting it by components and then use the summed quantity in some other table to do further calculations. How can I achieve this..
#views.py
class PurchaseCreateView(CreateView):
model = Purchase
fields = '__all__'
success_url = reverse_lazy("purchase_form")
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['purchases'] = Purchase.objects.all()
return context
#models.py
class Purchase(models.Model):
purchase_date = models.DateField()
invoice_no = models.CharField(max_length=200,unique=True)
supplier =models.ForeignKey(Supplier,on_delete=models.CASCADE)
components = models.ForeignKey(Components,on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
remarks = models.TextField(max_length=500,blank=True,null=True)
def __str__(self):
return str(self.pk)
# Below is the Model where I want to use the summed quantity for further calc
class IntermediateStage(models.Model):
producttype = models.ForeignKey(ProductType,on_delete=models.CASCADE)
components = models.ForeignKey(Components,on_delete=models.CASCADE)
processingstage = models.ForeignKey(ProcessingStage,on_delete=models.CASCADE)
unitsrequired = models.PositiveIntegerField()
quantity = models.PositiveIntegerField(blank = True)**#want to store summed qty here**
total_quantity = models.IntegerField(blank= True)
class Meta:
unique_together = [['producttype','components','processingstage']]
def __str__(self):
return str(self.id)
#Components Model
class Components(models.Model):
name = models.CharField(max_length=100,unique=True)
producttype = models.ManyToManyField(ProductType, through='IntermediateStage')
def __str__(self):
return self.name
how to get total sum of methods in django using agregate ? I used this for fields and it work fine but for method it doesn t return anything.
class Invoice(models.Model):
date = models.DateField(default=timezone.now)
client = models.ForeignKey('Client',on_delete=models.PROTECT)
def total(self):
total = self.invoiceitem_set.aggregate(sum=Sum('subtotal'))
return round(total[("sum")] or 0, 2)
class InvoiceItem(models.Model):
invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.PROTECT)
price = models.DecimalField(max_digits=20, decimal_places=2)
quantity = models.DecimalField(max_digits=20, decimal_places=2)
def subtotal(self):
return self.price * self.quantity
You can not reference a method, since the database does not know anything about subtotal. You thus should work with F objects [Django-doc] to multiply the price with the quantity:
from django.db.models import F
class Invoice(models.Model):
date = models.DateField(default=timezone.now)
client = models.ForeignKey('Client',on_delete=models.PROTECT)
def total(self):
return round(self.invoiceitem_set.aggregate(
sum=Sum(F('price') * F('quantity'))
)['sum'] or 0, 2)
With an F object, you refer to a field with that name.
I have two model as below
class Product(models.Model):
title = models.CharField(max_length=128)
slug = models.SlugField()
price = models.DecimalField(default=0.0,decimal_places=2,max_digits=15,validators=[MinValueValidator(Decimal('0.00'))])
def __str__(self):
return str(self.title)
class OrderItem(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f"{self.quantity} of {self.product.title}"
def subtotal(self):
return self.quantity * self.product.price
I want the total of all subtotal using aggregate but
total1 = OrderItem.objects.all().aggregate(total=Sum(F('product.price') * F('quantity')))['total']
returns Cannot resolve keyword 'product.price' into field. Choices are: id, order, product, product_id, quantity and
total2 = OrderItem.objects.all().aggregate(total=Sum(F('subtotal') * F('quantity')))['total']
returns Cannot resolve keyword 'subtotal' into field. Choices are: id, order, product, product_id, quantity, error
After some research I found that
from django.db.models import Sum, F
total = OrderItem.objects.all().aggregate(total=Sum(F('product__price') * F('quantity')))['total']
will do the work
Im quite lost in this models, i want to Enter data in CourseScore. Course score will point to one student, and one course which the student registered.
I want to do automatic calculation at the time of data entry.
from django.db import models
from student.models import Student
# Create your models here.
class Course(models.Model):
name = models.CharField(max_length=200)
finternalmark=models.IntegerField(default=40)
fexternalmark = models.IntegerField(default=100)
fullmark = models.IntegerField()
def CalculateFullMark(self):
self.fullmark = self.finternalmark + self.fexternalmark
def __str__(self):
return f'{self.name}-{self.fintegermark}-{self.fexternalmark}'
class CourseRegistration(models.Model):
student = models.OneToOneField(Student, on_delete=models.CASCADE)
courses = models.ManyToManyField(Course)
def __str__(self):
return f'{self.student}'
class CourseScore(models.Model):
#entering marks for one course
CourseRegn = models.OneToOneField(CourseRegistration, on_delete=models.CASCADE)
internalmark = models.IntegerField()
externalmark = models.IntegerField()
marks = models.IntegerField()
def CalculateMarks(self):
self.marks = self.internalmark + self.externalmark
class SemesterResult(models.Model):
student = models.OneToOneField(Student, on_delete=models.CASCADE)
courses= models.ForeignKey(CourseScore,on_delete=models.CASCADE) # course in which the student is registered and marks are entered
totalmarks=models.IntegerField()
grandtotal = models.IntegerField()
def CalculateTotalMarks(self):
pass
#calculate totalmarks = sum of marks scored in courses that the students opted
def CalculateGrandTotal(self):
pass
#calculate grandtotal = sum of all fullmarks of the course that the student opted
I suggest you make the attributes you want to automatically calculate property methods using the #property decorator instead of calculating it in your model function :
#property
def marks(self):
return self.internalmark + self.externalmark