2015-04-25 54 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