【问题标题】:Django query get common items based on attributeDjango查询根据属性获取常用项目
【发布时间】:2015-04-25 06:33:31
【问题描述】:

我有一个模型如下:

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 中具有相同名称的商品。我有一个很大的号码。每个供应商的商品数量可能高达 10,000 件,因此需要一种有效的方法吗?

【问题讨论】:

  • 从 1.11 版本开始,django 查询集有一个内置的交集和差分方法。我已将其添加为将来参考的答案

标签: django django-queryset set-theory


【解决方案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 的所有价格。使用此代码代替之前的 sn-p。

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)

【讨论】:

  • 这个很好用,还有一件事,我能找到和普通商品的价格差异吗?
【解决方案2】:

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,了解更详细的用例。

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多