django 一起使用aggregate() 和distinct()

问题描述 投票:0回答:1

我有一个具有以下属性的过滤器集:

dosFromGte = filters.DateFilter(method="search_by_dos_from_gte", lookup_expr="gte")
dosToLte = filters.DateFilter(method="search_by_dos_from_lte", lookup_expr="lte")

# One of these methods:

def search_by_dos_from_lte(self, queryset: Chart, name: str, value: str) -> Chart:
    return queryset.annotate(max_dos=Min("diagnosis__dos_from")).filter(max_dos__lte=value)

# using annotate and aggregate Min().

我需要运行一些注释,然后只获取不同的 id。

queryset = self.filter_queryset(self.get_queryset().exclude(state__in=repo_exclude))
queryset = queryset.annotate(
            ChartId=F("chart_id")
        ).values(
            "ChartId"
        ).distinct("id")

当我应用这些过滤器时

?clientId=11&project=56&dosFromGte=2023-08-17&dosToLte=2023-08-19
,它会尝试运行
Min()
,然后在
ids
上进行区分。

这给出了

NotImplementedError("aggregate() + distinct(fields) not implemented.")

所以我试着解决一下

queryset.values(
            "id", "ChartId"
        )
# remove duplicate charts based on pk, i.e. id
df = df.drop_duplicates('id')
df = df.drop('id', axis=1)

这感觉就像是一种黑客和肮脏的工作。

有没有更干净的 ORM 方法来做到这一点?

python django orm django-annotate django-aggregation
1个回答
0
投票

这里的主要挑战是 Django 不支持直接在 annotate() 调用之后对字段使用distinct(),这就是你遇到 NotImplementedError 的原因。

可以使用子查询单独处理注解,然后根据注解的子查询结果过滤主查询集。这种方法避免了在注释()之后直接使用distinct()。

© www.soinside.com 2019 - 2024. All rights reserved.