Python django中的查询优化
我想使用django orm优化循环代码,因为它需要41个查询,因为循环显示在django调试工具栏中,我已经用django orm说明了我的模型,有一个循环,我需要使用orm方法进行优化,以避免循环Python django中的查询优化,python,mysql,django,django-models,orm,Python,Mysql,Django,Django Models,Orm,我想使用django orm优化循环代码,因为它需要41个查询,因为循环显示在django调试工具栏中,我已经用django orm说明了我的模型,有一个循环,我需要使用orm方法进行优化,以避免循环 class Bills(models.Model): library=models.ForeignKey(Library,null=True) customer=models.ForeignKey(Customer, null=True) total_price = mod
class Bills(models.Model):
library=models.ForeignKey(Library,null=True)
customer=models.ForeignKey(Customer, null=True)
total_price = models.FloatField()
History = '1'
Physics = '2'
Maths = '3'
Book_Category=(
(History,'History'),
(Physics,'Physics'),
(Maths,'Maths')
)
book_category_type=models.CharField(max_length=2,choices=Book_Category)
这是存储特定客户的所有账单的账单模型
class LibraryOrder(models.Model):
hotel=models.ForeignKey(Hotel,null=True)
library = models.ForeignKey(Library,null=True)
customer=models.ForeignKey(Customer,null=True)
library_item = models.ForeignKey(LibraryItem,null=True)
quantity = models.FloatField()
total_price = models.FloatField()
comments=models.TextField(null=True)
bill=models.ForeignKey(Bills,null=True)
ORDER_STATUS = (
(NOT_PROCESSED, 'NotProcessed'),
(PROCESSING, 'Processing'),
(PROCESSED,'processed'),
)
order_status = models.CharField(max_length=3, choices=ORDER_STATUS, default=NOT_PROCESSED)
这是当一些客户订购图书馆项目中的某些书籍时的订单模型
现在我用的是:
customers = Customer.objects.filter(library="1").exclude(customer_status='2')
bills = Bills.objects.filter(library="1", customer=customers, book_category_type="1")
for bill in bills:
# if bill.order_type == "1":
not_processed_order = LibraryOrder.objects.filter(bill=bill, order_status="1")
notprocessed_lists.append(not_processed_order)
processing_order = LibraryOrder.objects.filter(bill=bill, order_status="2")
processing_lists.append(processing_order)
processed_order = LibraryOrder.objects.filter(bill=bill, order_status="3")
processed_lists.append(processed_order)
正在循环的账单是通过orm获取账单数组的循环,就像在图书馆订单中,我使用账单作为外键获取订单详细信息,并推送到数组中以在html中显示一样
我想优化django orm方法,我已经指定将两行转换为单行,这些列表是单独的,因为它显示在html的单独选项卡中。在这个特定场景中,您可以使用与自定义
预回迁
对象相关的预回迁来预回迁必要的数据,而不在循环内进行任何查询
customers = Customer.objects.filter(library="1").exclude(customer_status='2')
bills = Bills.objects.filter(library="1", customer=customers, book_category_type="1").prefetch_related(
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="1"), to_attr='not_processed_orders'),
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="2"), to_attr='processing_orders'),
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="3"), to_attr='processed_orders'),
)
for bill in bills:
notprocessed_lists.append(bill.not_processed_orders)
processing_lists.append(bill.processing_orders)
processed_lists.append(bill.processed_orders)
这样,您将有3个查询(每个prefetch
对象1个查询),而不是40多个查询
您可以进一步优化if到1个查询,但是您必须在python代码中做更多的工作:
customers = Customer.objects.filter(library="1").exclude(customer_status='2')
bills = Bills.objects.filter(library="1", customer=customers, book_category_type="1").prefetch_related('libraryorder_set')
for bill in bills:
not_processed_orders = []
processing_orders = []
processed_orders = []
for order in bill.libraryorder_set.all():
if order.status == '1':
not_processed_orders.append(order)
elif order_status == '2':
processing_orders.append(order)
elif order_status == '3':
processed_orders.append(order_status)
notprocessed_lists.append(bill.not_processed_orders)
processing_lists.append(bill.processing_orders)
processed_lists.append(bill.processed_orders)
然而,为了学习如何钓鱼,我建议您阅读以下文档中的文章:
在此特定场景中,您可以将prefetch\u related
与自定义prefetch
对象一起使用,以预取必要的数据,而不在循环内进行任何查询
customers = Customer.objects.filter(library="1").exclude(customer_status='2')
bills = Bills.objects.filter(library="1", customer=customers, book_category_type="1").prefetch_related(
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="1"), to_attr='not_processed_orders'),
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="2"), to_attr='processing_orders'),
Prefetch('libraryorder_set', queryset=LibraryOrder.objects.filter(order_status="3"), to_attr='processed_orders'),
)
for bill in bills:
notprocessed_lists.append(bill.not_processed_orders)
processing_lists.append(bill.processing_orders)
processed_lists.append(bill.processed_orders)
这样,您将有3个查询(每个prefetch
对象1个查询),而不是40多个查询
您可以进一步优化if到1个查询,但是您必须在python代码中做更多的工作:
customers = Customer.objects.filter(library="1").exclude(customer_status='2')
bills = Bills.objects.filter(library="1", customer=customers, book_category_type="1").prefetch_related('libraryorder_set')
for bill in bills:
not_processed_orders = []
processing_orders = []
processed_orders = []
for order in bill.libraryorder_set.all():
if order.status == '1':
not_processed_orders.append(order)
elif order_status == '2':
processing_orders.append(order)
elif order_status == '3':
processed_orders.append(order_status)
notprocessed_lists.append(bill.not_processed_orders)
processing_lists.append(bill.processing_orders)
processed_lists.append(bill.processed_orders)
然而,为了学习如何钓鱼,我建议您阅读以下文档中的文章: