Python 使用分支优化循环中的Django查询
我正在处理一个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
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()
的调用来执行此操作。是的,但这会使查询速度减慢更多..:/