Django находит все строки, соответствующие критериям 2 столбцов

Представьте себе модель Event следующим образом

name email
A u1@example.org
B u1@example.org
B u1@example.org
C u2@example.org
B u3@example.org
B u3@example.org
A u4@example.org
B u4@example.org

Я хочу найти все электронные письма, которые содержат имена A и B. В моем примере ["u1@example.org", "u4@example.org"]

Сегодня я делаю

emails = [
    e["email"]
    for e in models.Event.objects.filter(name__in=["A", "B"])
    .values("email")
    .annotate(count=Count("id"))
    .order_by()
    .filter(count__gt=1)
]

Это не работает, потому что я также получаю дубликаты писем, содержащих только одно имя (например, u3@example.org).

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

from django.db import connection

def get_random_events(request):
    cursor = connection.cursor()
    cursor.execute("SELECT DISTINCT email FROM event WHERE name = 'A' OR 'B'")
    for row in cursor:
        print(row[0])

    return  render(request, 'blank.html')

Что касается ORM, проблема заключается в последней части запроса, кажется, что невозможно правильно построить предложение WHERE. Моей лучшей попыткой было использование Q lookups, все равно... та же проблема:

RandomEvent.objects.values('email').distinct().filter(Q(name='B') | Q(name='A'))

# Query Structure
SELECT DISTINCT email FROM random_event WHERE (name = 'B' OR name = 'A')

Попробовав различные подходы, я нашел решение


events = ["A", "B"]
emails = [
    e["email"]
    for e in models.Event.objects.filter(name__in=events)
    .values("email")
    .annotate(count_name=Count("name", distinct=True))
    .order_by()
    .filter(count_name=len(events))
]

Мне нужно сгруппировать по email и подсчитать количество отдельных name и отфильтровать по количеству, равному количеству событий.

Вернуться на верх