如何在Django中获得两个查询集的区别?

时间:2011-05-10 06:09:32

标签: python django django-queryset

我必须查询集。 alllists和订阅列表

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

我需要一个名为unsubscriptionlist的查询集,它拥有除了订阅列表中的记录之外的所有alllists记录。怎么做到这一点?

4 个答案:

答案 0 :(得分:15)

您应该可以使用设置操作差异来帮助:

set(alllists).difference(set(subscriptionlists))

答案 1 :(得分:12)

自Django 1.11以来,QuerySets在其他新方法中都有difference()方法。 (来源: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

另见:https://stackoverflow.com/a/45651267/5497962

答案 2 :(得分:9)

我在这里看到两个选项。

1。手动过滤(非常难看)

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。只需进行另一次查询

diff = List.objects.filter(datamode = 'A').exclude(member__id=memberid, datamode='A')

答案 3 :(得分:3)

怎么样:

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

取消订阅者应该是订阅列表的反转。

Brian的答案也会起作用,尽管set()很可能会对查询进行评估,并且在将这两个集合评估到内存中时会受到性能影响。此方法将保持延迟初始化,直到您需要数据。