简体   繁体   中英

Django - How to combine 2 queryset and filter to get same element in both queryset?

I have a model:

class LocationItem(models.Model):
    location = models.ForeignKey(Location, on_delete=models.CASCADE)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    stock_qty = models.IntegerField(null=True)

Example: I have some data like this:

------------------------------
| ID | Item | Location | Qty |
------------------------------
| 1  |  1   |    1     |  10 |
------------------------------
| 2  |  2   |    1     |  5  |
------------------------------
| 3  |  1   |    2     |  2  |
------------------------------
| 4  |  3   |    1     |  4  |
------------------------------
| 5  |  3   |    2     |  20 |
------------------------------

I have 2 queryset to get items of each location:

location_1 = LocationItem.objects.filter(location_id=1)
location_2 = LocationItem.objects.filter(location_id=2)

Now I want to combine 2 queryset above into 1 and filter only same items in both 2 location such as result of this example above is [Item 1, Item 3] because item 1 and 3 belong to both location 1 and 2

You can combine django query set using following expression

location_1 = LocationItem.objects.filter(location_id=1)
location_2 = LocationItem.objects.filter(location_id=2)

location = location_1 | location_2

Above combine expression works on same model filter query set.

Try this one

from django.db.models import Count
dupes = LocationItem.objects.values('item__id').annotate(Count('id')).order_by().filter(id__count__gt=1)
LocationItem.objects.filter(item__=[i['item__id'] for i in dupes]).distinct('item__id')

May be above solution help.

If you want both conditions to be true, then you need the AND operator ( & )

from django.db.models import Q

Q(location_1) & Q(location_2)

You can do this by piping the filters. The result of a filter is a queryset. So after the first filtering, the result will be [Item1, Item2 , Item3] and then second filter will be applied on the resulting queryset which leads [Item1, Item3] . For eg.

Item.objects.filter(locationitem_set__location = 1).filter(locationitem_set__location = 2)

PS Not tested. Hope this works.

Try this:

location1_items_pk = LocationItem.objects.filter(
    location_id=1
).values_list("item_pk", flat=true)

Result = Location.objects.filter(
    item_pk__in=location1_items_pk, location_id=2
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM