Reputation: 391
I have the following models in my application in which I add items to a cart and can remove them too. The adding and removing of a cart item has been achieved through my views but what i want is that about how can I do this in Admin.
class Product(models.Model):
product_name=models.CharField(max_length=32)
price=models.IntegerField()
class Cart(models.Model):
cust_id=models.ForeignKey(User, on_delete=models.CASCADE)
count=models.IntegerField(default=0)
total=models.IntegerField(default=0)
class Cart_Item(models.Model):
item=models.ForeignKey(Product, blank=True, null=True, on_delete=models.CASCADE)
quantity=models.IntegerField()
cart=models.ForeignKey(Cart, on_delete=models.CASCADE)
What I want to achieve in Admin is that that if I add or remove a Cart_Item
object in Admin, it should update the corresponding values of count
and total
in Cart
accordingly for that particular user
Upvotes: 1
Views: 261
Reputation: 302
I would consider count
and total
to be model methods of Cart
, like this:
from django.db.models import Sum
class Product(models.Model):
product_name=models.CharField(max_length=32)
price=models.IntegerField()
class Cart(models.Model):
cust_id=models.ForeignKey(User, on_delete=models.CASCADE)
# Model Property
@property
def count(self):
return Cart_Item.objects.filter(cart=self).count()
@property
def total(self):
return Cart_Item.objects.filter(cart=self).item.aggregate(Sum('price'))
class Cart_Item(models.Model):
item=models.ForeignKey(Product, blank=True, null=True, on_delete=models.CASCADE)
quantity=models.IntegerField()
cart=models.ForeignKey(Cart, on_delete=models.CASCADE)
You can then access the count and total just like you would access any other field, like this:
cart = Cart(cust_id=user)
items_in_cart = cart.items
total_balance = cart.amount
We can also use the related_name attribute of the model to access the children or "access the model backward":
from django.db.models import Sum
class Product(models.Model):
product_name=models.CharField(max_length=32)
price=models.IntegerField()
class Cart(models.Model):
cust_id=models.ForeignKey(User, on_delete=models.CASCADE)
# Model Property
@property
def count(self):
return self.cart_items.count()
@property
def total(self):
return self.cart_items.item.aggregate(Sum('price'))
class Cart_Item(models.Model):
item=models.ForeignKey(Product, blank=True, null=True, on_delete=models.CASCADE)
quantity=models.IntegerField()
cart=models.ForeignKey(Cart, on_delete=models.CASCADE, related_name='cart_items')
We need model methods because count
and total
are being generated dynamically.
If you really would like the model methods to be fields of Cart, you can try this solution.
Please comment if this doesn't work, I'm new to Django.
Upvotes: 2