Django находит все строки, соответствующие критериям 2 столбцов
Представьте себе модель Event следующим образом
name | |
---|---|
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
и отфильтровать по количеству, равному количеству событий.