Reputation: 21
class Item(models.Model):
CATEGORY = (
('Gudang Kering', 'Gudang Kering'),
('Gudang Basah','Gudang Basah'),
)
name = models.CharField(max_length=200,null= True)
stock = models.IntegerField(default='0', blank=False, null=True)
category = models.CharField(max_length=200,null= True,choices=CATEGORY)
description = models.CharField(max_length=200,null= True, blank= True)
date_created = models.DateTimeField(auto_now_add= True)
tags = models.ManyToManyField(Tag)
class Issue(models.Model):
STATUS = (
('Pending', 'Pending'),
('Granted','Granted'),
('Denied','Denied'),
)
customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
item = models.ForeignKey(Item, null=True, on_delete= models.SET_NULL)
quantity = models.IntegerField(default='0', blank=False, null=True)
date_created = models.DateTimeField(auto_now_add=True, auto_now=False)
status = models.CharField(max_length=200,null= True, choices=STATUS)
class Receive(models.Model):
STATUS = (
('Pending', 'Pending'),
('Granted','Granted'),
('Denied','Denied'),
)
customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
item = models.ForeignKey(Item, null=True, on_delete= models.SET_NULL)
quantity = models.IntegerField(default='0', blank=False, null=True)
date_created = models.DateTimeField(auto_now_add=True, auto_now=False)
status = models.CharField(max_length=200,null= True, choices=STATUS)
"Hello,sorry im trying to learn django and want to ask,how to write a query to calculate objects where if the 2 have the same item and status granted ,it will calculate stock - quantity(issue) + quantity(receive), i want to save the value to be new value of stock in database"
Upvotes: 2
Views: 67
Reputation: 51978
There is no need to store same information twice. It will make this solution more confusing. You can add these values in runtime. For example:
Solution One: You can just annotate
the value of quantity in the queryset directly. No need to store that additional information in the stock attribute of Item
model. For example:
from django.db.models import Q, F, Sum
items = Item.objects.annotate(issue_q=Sum('issue__quantity', filter=Q(issue__status="GRANTED")).annotate(total=F('stock')-F('issue_q'))
for item in items:
print(item.total)
Solution Two: add a property method to display total value:
class Item(models.Model):
...
@property
def total(self):
return self.stock - self.item_set.filter(status="GRANTED").aggregate(quantity_s=Sum('quantity'))['quantity_s']
for item in Item.objects.all():
print(item.total)
BTW, this solutions is less efficient then first, as it makes multiple queries to DB.
Upvotes: 1
Reputation: 2451
Item()
and Customer()
first as they are set as Foreign Keys in Issue()
Issue()
and assign corresponding values to fieldsItem.stock
use the Issue.quantity
and Item.stock
values which already we have# c_id and i_id should be fetched from post or any other way
customer_obj = Customer.objects.get(id=c_id)
item_obj = Item.objects.get(id=i_id)
# create an object of Issue and assign values
issue_obj = Issue()
issue_obj.customer = customer_obj
issue_obj.item = item_obj
# like so assign values to other fields also and save Issue object
issue_obj.save()
# calculate stock and save the Item object
item_obj.stock = item_obj.stock - issue_obj.quantity
item_obj.save()
When Foreign Key is used, the object of the model class should be assigned to that field. eg: customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
is a field in Issue()
. Inorder to save the instance of Issue()
we need to assign the object of Customer()
to customer field of Issue object.
Upvotes: 1