Как использовать объекты Django Q с ~Q() внутри annotate(filter=...), чтобы исключить значение?
Я занимаюсь рефакторингом устаревшего задания Django, чтобы использовать annotate с отфильтрованными Count агрегациями вместо запроса каждой записи по отдельности (избегая проблемы N + 1).
Я хочу подсчитать количество связанных EventReport объектов для каждого Store, исключая те, где status="C".
Итак, я написал что-то вроде:
stores_with_monitoring_enabled.annotate(
total_cards=Count(
'eventreport',
filter=Q(
eventreport__event_at__gte=day_30_days_ago_start,
eventreport__event_at__lte=yesterday_end
) & ~Q(eventreport__status='C')
),
# ... etc
Но Джанго поднял SyntaxError: positional argument follows keyword argument.
Я тоже пытался:
# ... etc
filter=Q(
eventreport__event_at__gte=start_date,
eventreport__event_at__lte=end_date
) & ~Q(eventreport__status="C")
# ... etc
Но я не уверен, что это правильный шаблон внутри фильтра annotate().
Я ожидал получить только связанные объекты, где `status != "C" без каких-либо ошибок.
PS: Я просмотрел другие решения для StackOverflow и предложения по этому: Как мне сделать неравенство в фильтрации набора запросов Django?, но я не смог заставить его работать при использовании Q() вместе с ~Q() с другими kwargs.
Каков наилучший подход для выражения status != 'C' внутри предложения Count(..., filter=...)?
Но Django вызвал ошибку синтаксиса: позиционный аргумент следует за аргументом ключевого слова.
Нет, Python выдает эту ошибку. Вероятно, потому, что у вас есть другие, неименованные параметры, например:
stores_with_monitoring_enabled.annotate(
total_cards=Count(
'eventreport',
filter=Q(
eventreport__event_at__gte=day_30_days_ago_start,
eventreport__event_at__lte=yesterday_end
) & ~Q(eventreport__status='C')
),
Count('some_other_count'),
)
теперь в Python вы всегда ставите позиционные параметры перед именованными параметрами, поэтому f(x, y=z) допустимо, f(y=z, x) s> - это , а не, поэтому вам следует проверить вызов метода, который вызывает ошибку, и поискать такие шаблоны.