如何使另一个模型的特定模型字段动态化

时间:2019-06-11 08:58:55

标签: django django-models orm

我有两个模型Damaged和Product.Product模型中产品的数量取决于存储在另一个表中的Damaged_quantity值,例如,如果Damaged_quantity在损伤表中,那么产品中的数量值应如果是quantity-damaged_quantity,请设为damaged.product_id == product.id。我尝试过这样,但无法正常工作

  

models.py

class Damaged(models.Model):
    product = models.ForeignKey('Product', on_delete=models.CASCADE)
    damaged_quantity = models.IntegerField(default=0)

    def __str__(self):
        return self.product


class Product(models.Model):
    name = models.CharField(max_length=250)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)
    quantity = models.IntegerField() 
  

views.py我在自己的视图中访问产品查询集

def list_products(request):
products = Product.objects.annotate(damaged_product_quantity=Sum('damagedproducts__damaged_quantity')).annotate(
        real_quantity=ExpressionWrapper(F('quantity') - F('damaged_product_quantity'), output_field=IntegerField()))
  

list_product_template。在显示real_quantity时,如果Damage.damaged_quanity和product.quantity相等,则它不会更改值。不是变为0,它不会更改值。在其他情况下,它工作正常。

                {% if not product.real_quantity %}
                {{product.quantity}}
                {% elif product.real_quantity == product.quantity %}
                 0
                {% else %}
                {{ product.real_quantity }}
                {% endif %}
  

product_detail页面

def product_detail(request, slug):
    product = get_object_or_404(Product, slug=slug)
    damaged = Damaged.objects.all()

    return render(request, 'pos/product_detail.html', {'product': product,'damaged':damaged})
  

product_detail模板。我想像这样在添加破损产品后获得当前的产品数量,但工作不正常。它给了我{% if %}{% else %}的一部分。我该如何解决?

product quantity:
{% for damage in damaged %}
{% if product.id == damage.product_id %}
{{product.quantity|subtract:damage.damaged_quantity}}
{% else %}
{{product.quantity}}
{% endif %}
{% endfor %}

1 个答案:

答案 0 :(得分:1)

我认为您需要在Damaged模型中覆盖save方法:

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为产品附加价值,以便您可以在需要时查询。例如:

为此,让我们在Damaged模型中添加一个related_name字段:

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 %}