From 4acd80718d389bd3555653f19ddbf7f1047d02b2 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 13 Mar 2026 16:35:12 +0800 Subject: [PATCH] fix: avoid duplicate rows in complex reverse queries Add an optional distinct flag to complex query payload and deduplicate by primary key before annotate/order flow, so reverse-join filtering does not return repeated records. Made-with: Cursor --- apps/utils/mixins.py | 6 ++++++ apps/utils/serializers.py | 1 + 2 files changed, 7 insertions(+) diff --git a/apps/utils/mixins.py b/apps/utils/mixins.py index 5e0bd9ea..990d5926 100755 --- a/apps/utils/mixins.py +++ b/apps/utils/mixins.py @@ -252,6 +252,7 @@ class ComplexQueryMixin: queryset = self.get_queryset() querys = vdata.get('querys', []) annotate_field_list = vdata.get('annotate_field_list', []) + distinct = vdata.get('distinct', True) if not querys: new_qs = queryset @@ -274,6 +275,11 @@ class ComplexQueryMixin: new_qs = new_qs | one_qs except Exception as e: raise ParseError(str(e)) + + # 反向关联(右到左)查询容易因 JOIN 膨胀产生重复行,这里按主键回查去重 + if distinct: + pk_name = queryset.model._meta.pk.attname + new_qs = queryset.filter(**{f"{pk_name}__in": new_qs.values(pk_name)}) if annotate_field_list: annotate_dict = getattr(self, "annotate_dict", {}) diff --git a/apps/utils/serializers.py b/apps/utils/serializers.py index 263ec5f2..9a2f7f91 100755 --- a/apps/utils/serializers.py +++ b/apps/utils/serializers.py @@ -83,6 +83,7 @@ class ComplexSerializer(serializers.Serializer): page = serializers.IntegerField(min_value=0, required=False) page_size = serializers.IntegerField(min_value=1, required=False) ordering = serializers.CharField(required=False) + distinct = serializers.BooleanField(required=False, default=True, label="是否按主键去重") querys = serializers.ListField(child=QuerySerializer( many=True), label="查询列表", required=False) annotate_field_list = serializers.ListField(child=serializers.CharField(), label="RawSQL字段列表", required=False)