How to get the difference of two querysets in Djan

2019-02-05 20:37发布

I have to querysets. alllists and subscriptionlists

alllists = List.objects.filter(datamode = 'A')
subscriptionlists = Membership.objects.filter(member__id=memberid, datamode='A')

I need a queryset called unsubscriptionlist, which possess all records in alllists except the records in subscription lists. How to achieve this?

4条回答
贼婆χ
2楼-- · 2019-02-05 21:24

How about:

subscriptionlists = Membership.objects.filter(member__id=memberid, datamode='A')
unsubscriptionlists = Membership.objects.exclude(member__id=memberid, datamode='A')

The unsubscriptionlists should be the inverse of subscription lists.

Brian's answer will work as well, though set() will most likely evaluate the query and will take a performance hit in evaluating both sets into memory. This method will keep the lazy initialization until you need the data.

查看更多
Fickle 薄情
3楼-- · 2019-02-05 21:27

Since Django 1.11, QuerySets have a difference() method amongst other new methods. (Source: https://docs.djangoproject.com/en/1.11/releases/1.11/#models)

qs_diff = qs_all.difference(qs_part)    # Capture elements that are in qs_all but not in qs_part

Also see: https://stackoverflow.com/a/45651267/5497962

查看更多
啃猪蹄的小仙女
4楼-- · 2019-02-05 21:28

Well I see two options here.

1. Filter things manually (quite ugly)

diff = []
for all in alllists:
    found = False
    for sub in subscriptionlists:
        if sub.id == all.id:
            found = True 
            break
    if not found:
        diff.append(all)

2. Just make another query

diff = List.objects.filter(datamode = 'A').exclude(member__id=memberid, datamode='A')
查看更多
女痞
5楼-- · 2019-02-05 21:40

You should be able to use the set operation difference to help:

set(alllists).difference(set(subscriptionlists))
查看更多
登录 后发表回答