2016-08-17 67 views
0

我想用Django的ORM,因爲它正在因爲環路的41個查詢優化循環代碼在Django的調試工具欄裏結果表明,我已表示我的模型與Django的ORM並有一個循環其中,i需要使用ORM方法來優化這樣我可以避免環路。優化查詢在Django

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

回答

4
not_processed_order = LibraryOrder.objects.filter(bill__library="1", bill__book_category_type="1", order_status="1", bill__customer__library='1').exclude(bill__customer__status='2') 
processing_order = LibraryOrder.objects.filter(bill__library="1", bill__book_category_type="1", order_status="2", bill__customer__library='1').exclude(bill__customer__status='2') 
processed_order = LibraryOrder.objects.filter(bill__library="1", bill__book_category_type="1", order_status="3", bill__customer__library='1').exclude(bill__customer__status='2') 
0

顯示在這種特定情況下,你可以使用prefetch_related與定製Prefetch對象/ s到預取所需的數據,而不是使環內的任何查詢。

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+。

,可以優化,如果進一步向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) 

但是爲了瘦如何釣魚,我的建議是看看在從文檔的以下文章: