0

我有一个模型如下:

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 个项目的项目,所以需要一种有效的方法来做到这一点?

4

2 回答 2

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))

更新:要找到价格差异,您可以遍历找到的常见物品:

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)

这会为每个找到的项目添加一个 db hit,但如果您有少量常见项目,那么这个解决方案就可以正常工作。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)
于 2015-04-25T07:32:40.140 回答
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)

有关更详细的用例,请参阅我的博客文章。

于 2017-08-09T02:32:27.070 回答