Я думаю, вам нужно переопределить метод сохранения в Damaged
модели:
class Damaged(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE)
damaged_quantity = models.IntegerField(default=0)
def __str__(self):
return self.product
def save(self, *args, **kwargs):
super(Damaged, self).save(*args, **kwargs)
self.product.quantity = self.product.quantity - self.damaged_quantity
self.product.save()
Но это решение может быть несовместимым.Например, если вы попытаетесь обновить поврежденную модель, то значение продукта будет обновлено снова.
Я бы порекомендовал использовать annotation
, чтобы связать значение с продуктом, чтобы при необходимости можно было запрашивать.Например:
Для этого добавим поле related_name
в Damaged
модель:
class Damaged(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE, related_name='damagedproducts')
damaged_quantity = models.IntegerField(default=0)
Использование:
from django.db.models import Sum, F, IntegerField
products = Product.objects.annotate(damaged_product_quantity=Sum('damagedproducts__damaged_quantity')).annotate(real_quantity=ExpressionWrapper(F('quantity') - F('damaged_product_quantity'), output_field=IntegerField())
real_quantity_more_than_ten = products.filter(real_quantity__gt=10)
for p in real_quantity_more_than_ten:
print(p.real_quantity)
Обновление
from django.db.models import Sum
def product_detail(request, slug):
product = get_object_or_404(Product, slug=slug)
damaged = product.productdamaged.all()
if damaged.exists():
damage_amount = damaged.aggregate(d_amount = Sum('productdamaged__damaged_quantity')).get('d_amount', 0)
else:
damage_amount = 0
return render(request, 'pos/product_detail.html', {'product': product,'damage_amount':damage_amount})
# template
{% if damage_amount != 0 %}
{{product.quantity|subtract:damage_amount}}
{% else %}
{{product.quantity}}
{% endif %}