在 Django 数据库查询中计算百分比

Calculate percentage In Django Database Query

我正在尝试使用单个查询来计算帐单中所有含税服务的总成本。我不明白我哪里错了。

型号:

class Bill(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    number = models.CharField(max_length=100, blank=True)


class BillService(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    bill = models.ForeignKey(Bill, related_name='billservices', on_delete=models.CASCADE)
    service = models.ForeignKey(Service, on_delete=models.CASCADE)

class Service(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    business = models.ForeignKey(Business, related_name='services', on_delete=models.CASCADE, blank=True)
    short_code = models.IntegerField(default=0)

class ServiceTax(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="servicetaxes")
    tax = models.ForeignKey(Tax, on_delete=models.CASCADE)

class Tax(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    business = models.ForeignKey(Business, related_name='taxes', on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    tax = models.FloatField(validators=[MinValueValidator(0), MaxValueValidator(100)], default=0)

我想得到一个单一的值,即账单的总费用

    value = bill.billservices.all()
                .annotate(sum_of_taxed_percentages=Subquery(
                        Service.objects.filter(billservice=OuterRef('id'))
                        .annotate(total_tax_value=Subquery(
                            ServiceTax.objects.filter(service=OuterRef('id'))
                            .values('tax')
                            .annotate(total_tax=Sum('tax__tax', output_field=FloatField()))
                            .values('total_tax')
                        )).annotate(taxed_value=F('price') + ((F('price') * F('total_tax_value')) / 100))
                       .values('taxed_value')
                       .annotate(total_services_taxed_value=Sum('taxed_value', output_field=FloatField()))
                       .values('total_services_taxed_value')
             ))

             print(value[0].sum_of_taxed_percentages)

错误:

'ManyToOneRel' object has no attribute 'select_format'

如果这是您计算百分比的地方:

taxed_value=F('price') + ((F('price') * F('total_tax_value')) / 100)

在这条战壕上:

((F('price') * F('total_tax_value')) / 100

我认为您需要更改一些括号:

(F('price') * (F('total_tax_value') / 100))

因为您首先需要将存储的百分比除以 100,然后将其乘以对象的价格,然后求和为对象的当前值:

taxed_value=F('price') + (F('price') * (F('total_tax_value') / 100))

检查是否有效,我不确定,似乎是一个简单的公式问题...

经过多次尝试和错误,我找到了解决方案。

   service_tax = ServiceTax.objects.filter(service=OuterRef('service')) \
                .values('tax__tax')
   value = bill.billservices.all() \
                .annotate(service_taxes=SQSum(service_tax)) \
                .annotate(service_price=F('service__price')) \
                .aggregate(total=Sum(F('service_price') + ((F('service_price') * F('service_taxes')) / 100),
                                     output_field=FloatField()))
   print(value)



class SQSum(Subquery):
    template = "(SELECT SUM(tax) FROM (%(subquery)s) _sum)"
    output_field = models.FloatField()