[Answer]-Django query get common items based on attribute

1๐Ÿ‘

I think that something like this should work:

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: To find the price difference you can just loop over the found common items:

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)

This adds a db hit for each found item but if you have a small number of common items then this solution will work just fine. For larger intersection you can load all prices from vendor_b_items in one query. Use this code instead of the previous snippet.

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)
๐Ÿ‘คcatavaran

0๐Ÿ‘

Starting from django 1.11, this can be resolved using the built in intersection and difference methods.

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)

See my blog post on this for more detailed use cases.

๐Ÿ‘คJose Cherian

Leave a comment