Как получить разницу двух наборов запросов в Django?

Я должен запросить наборы. все списки и подписки

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

Мне нужен набор запросов, называемый unsubscriptionlist, который обладает всеми записями во всех списках, кроме записей в списках подписки. Как этого добиться?

5 ответов

Начиная с Django 1.11, QuerySets имеет difference() метод среди других новых методов. (Источник: https://docs.djangoproject.com/en/1.11/releases/1.11/)

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

Также см.: /questions/34323234/prostoj-sposob-dlya-obedineniya-i-vyichitaniya-queryset-v-django/34323263#34323263

Вы должны быть в состоянии использовать установленную разницу операций, чтобы помочь:

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

Ну, я вижу два варианта здесь.

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

Как насчет:

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

Списки отписки должны быть обратными спискам подписки.

Ответ Брайана также будет работать, хотя set(), скорее всего, оценит запрос и снизит производительность при оценке обоих наборов в памяти. Этот метод будет сохранять ленивую инициализацию до тех пор, пока вам не понадобятся данные.

Если кто-то ищет способ сделать симметричную разницу, такой оператор недоступен в Django.

Тем не менее, это не так сложно реализовать, используяdifferenceиunion, и все это будет сделано в одном запросе:

      q1.difference(q2).union(q2.difference(q1))
Другие вопросы по тегам