Python 使用分支优化循环中的Django查询

Python 使用分支优化循环中的Django查询,python,django,database,performance,optimization,Python,Django,Database,Performance,Optimization,我正在处理一个Django项目,在某个视图上,我希望检索所有客户的所有付款单及其付款 主要查询如下: orders = PaymentOrder.objects.filter( created_date__gte=init_date, created_date__lte=end_date ).values( 'invoice_sat__comp_folio', 'created_date', 'client__name', 'client__last_name', 'to

我正在处理一个Django项目,在某个视图上,我希望检索所有客户的所有付款单及其付款

主要查询如下:

orders = PaymentOrder.objects.filter(
    created_date__gte=init_date, created_date__lte=end_date
).values(
    'invoice_sat__comp_folio', 'created_date', 'client__name',
    'client__last_name', 'total', 'status', 'pk', 'client__pk'
).order_by('-created_date')
另外,我想要每个订单的支付金额,我正在这样做:

for order in orders:
    order_payments = Payment.objects.filter(
        order__pk=order['pk']
    ).values('amount').aggregate(total=Sum('amount'))
    if order_payments['total'] is not None:
        to_pay = order['total'] - order_payments['total']
    else:
        to_pay = order['total']
    order.update(to_pay=to_pay)
这里的问题是,加载模板需要很长时间,我有15000个结果。是否有任何方法可以优化查询,或者更新订单的额外信息(支付金额)

非常感谢

型号更新:

class PaymentOrder(models.Model):
    STATUS = (
        (0, "Por Pagar"),
        (1, "Pagado"),
    )
    client = models.ForeignKey(Client, verbose_name='Cliente')
    invoice_sat = models.ForeignKey(InvoiceSAT, blank=True, null=True)
    invoice_period = models.DateField(verbose_name="Periodo de     Facturación")
    created_date = models.DateTimeField(verbose_name='Fecha de Creacion',
                                    default=datetime.datetime.now(),
                                    db_index=True)
    cancelled_date = models.DateField(verbose_name='Fecha de Cancelacion',
                                  default=None, null=True, blank=True)
    due_date = models.DateField(verbose_name="Fecha de Vencimiento")
    status = models.IntegerField(max_length=1, choices=STATUS, default=0)
    subtotal = models.DecimalField(max_digits=10, decimal_places=2,
                               verbose_name='Subtotal', default=0)
    total = models.DecimalField(max_digits=10, decimal_places=2,
                            verbose_name="Cantidad", default=0)

class Payment(models.Model):
    order = models.ForeignKey(PaymentOrder, verbose_name='Orden de Pago')
    payment_date = models.DateField(verbose_name="Fecha de Pago")
    amount = models.DecimalField(max_digits=10, decimal_places=2,
                             verbose_name="Cantidad a pagar")

select_related
可能是您想要的,这将使您避免在for循环中每次迭代都碰到db

orders = PaymentOrder.objects.filter(
    created_date__gte=init_date, created_date__lte=end_date
).order_by('-created_date').select_related('payment') # one giant hit to the db
for order in orders:
    order_payments = order.payment_set.values('amount').aggregate(total=Sum('amount'))
        #uses data already pulled from select_related so does not hit db

此处的文档:

发布您的模型。解决方案是:(1)尝试将其作为queryset更新,而不是在Python land中循环处理订单;(2)尝试通过一个查询将所有内容拉入,而不是在循环中再次命中数据库(
Payment.objects.filter…
等)。但是这里没有足够的信息来说明这是否真的有可能,更不用说你可以/应该怎么做了。我刚刚添加了我的模型。谢谢我认为这是行不通的,因为我的模型上的关系。Paymentor模式没有付款关系:/这就是为什么它是payment_set:P Django让你反向查找外键@jesucc29ohhh,我明白了。但是,我无法访问“payment\u set”,因为“order”实际上是一个dict(),并且我得到的“dict”对象没有属性“payment\u set”错误:(是的。您不必使用对
.values()
的调用来执行此操作。是的,但这会使查询速度减慢更多..:/