Как использовать объекты 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) - это , а не, поэтому вам следует проверить вызов метода, который вызывает ошибку, и поискать такие шаблоны.

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