2015-04-25 89 views
0

我有一個模型共同項目如下:Django的查詢得到基於屬性

class Item(models.Model): 
    VENDOR_CHOICES = (
     ('a', 'A'), 
     ('b', 'B') 
    ) 

    vendor = models.CharField(max_length=16, choices=VENDOR_CHOICES) 
    name = models.CharField(max_length=255) 
    price = models.DecimalField(max_digits=6, decimal_places=2) 

現在我有2種數據源,所以我從供應商A的項目和物品從供應商B.

在某些情況下,供應商A可能與供應商B不同,說供應商A有30個項目,供應商B有442個項目,其中只有6個項目是通用的。通用項目被定義爲具有完全相同名稱的項目。

我還需要找到供應商a和供應商b項目中常見項目的價格差異,這意味着供應商a和供應商b中具有相同名稱的項目。我有一個很大的沒有。的項目可能會高達每個供應商10K項目,所以需要一個有效的方法來做到這一點?

+0

從版本1.11開始,django查詢集具有內置的交集和差異方法。我已經添加了它作爲未來參考的答案 –

回答

1

我認爲,這樣的事情應該工作:

vendor_a_items = Item.objects.filter(vendor='a') 
vendor_b_items = Item.objects.filter(vendor='b') 

common_items = vendor_a_items.filter(
         name__in=vendor_b_items.values_list('name', flat=True)) 

UPDATE:要查找的價格差異,你可以只在發現的常見物品循環:

for a_item in common_items: 
    b_item = vendor_b_items.get(name=a_item.name) 
    print u'%s: %s' % (a_item.name, a_item.price - b_item.price) 

這增加了分貝擊中每個找到的項目,但如果你有少量的常見項目,那麼這種解決方案將工作得很好。對於較大的路口,您可以在一個查詢中加載vendor_b_items的所有價格。使用此代碼而不是以前的代碼片段。

common_items_d = {item.name: item for item in common_items} 
for b_item in vendor_b_items.filter(name__in=common_items_d.keys()): 
    print u'%s: %s' % (b_item.name, 
         common_items_d[b_item.name].price - b_item.price) 
+0

這完美的工作,只需一件事,我可以找到普通物品的價格差異嗎? – user3413046

+0

完美,謝謝! – user3413046

0

django 1.11開始,可以使用內置的相交和差分方法來解決此問題。

vendor_a_items = Item.objects.filter(vendor='a') 
vendor_b_items = Item.objects.filter(vendor='b') 
common_items = vendor_a_items.intersection(vendor_b_items) 
vendor_a_exclussive_items = vendor_a_items.difference(vendor_b_items) 
vendor_b_exclussive_items = vendor_b_items.difference(vendor_a_items) 

有關更多詳細用例,請參閱我的blog post