如何在Django中获得两个查询集的差异?

fcg9iug3  于 2022-11-26  发布在  Go
关注(0)|答案(5)|浏览(234)

我必须查询查询集合、所有列表和订阅列表。

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

我需要一个名为unsubscriptionlist的查询集,它拥有所有列表中除订阅列表外的所有记录。如何实现?

lmvvr0a8

lmvvr0a81#

从Django 1.11开始,QuerySets有了difference()方法和其他新方法:

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

另请参阅:https://stackoverflow.com/a/45651267/5497962

vd8tlhqk

vd8tlhqk2#

您应该能够使用set操作差异来帮助:

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

rkkpypqq3#

我有两个选择。

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')
envsm3lx

envsm3lx4#

怎么样:

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

unsubscriptionlists应该是订阅列表的逆列表。
Brian的答案同样有效,尽管set()很可能会对查询求值,并且在对两个集合求值时会影响内存性能。该方法将保持惰性初始化,直到需要数据。

vsmadaxz

vsmadaxz5#

如果有人在寻找对称差分的方法,Django中没有这样的操作符。
也就是说,使用differenceunion来实现它并不困难,而且这一切都将在一个查询中完成:

q1.difference(q2).union(q2.difference(q1))

相关问题