在过滤的查询集中获取重复记录

Duplicate records are fetched in filtered queriset

我有一些像这样的 | & 过滤器的复杂组合。

objs = objs.annotate(num_line=Count("lns")).\
    filter(Q(lns__id__in=lnIds) | (Q(sts__id__in=oIds) 
        & (Q(lns__id__in=lnIds) | Q(num_ln__lte=0))))

看起来不错,但结果有时会重复(具有相同的 ID)。

   id
    1
    2
    3
    3
    4
    5

我认为过滤器保证 return 唯一 ID,我错了吗??

或者是否可以省略重复的行??

class Obj(models.Model):
    created_at = models.DateTimeField(null=True)
    lns = models.ManyToManyField(Ln)
    sts = models.ManyToManyField(St)
    is = models.ManyToManyField(Is)
    pub_date = models.DateTimeField('date published')

不,如果你在一对多或多对多关系中过滤,它会创建一个与相关table的JOIN,如果多个对象匹配,那么这将导致屈服多次相同的值。

您可以使用 .distinct(..) (Django-doc) 来过滤重复的行。

objs = objs.filter(
    Q(lns__id__in=lnIds) |
    (Q(sts__id__in=oIds) & (Q(lns__id__in=lnIds) | Q(num_ln__lte=0))
)<b>.distinct()</b>

更有问题的是,如果您添加注释,那么这可能会导致计数也会计算重复项。您可以将 distinct=True [Django-doc] 添加到 Count(..) 表达式以防止:

objs = objs.annotate(
    num_line=Count('lns'<b>, distinct=True</b>)
).filter(
    Q(lns__id__in=lnIds) |
    (Q(sts__id__in=oIds) & (Q(lns__id__in=lnIds) | Q(num_ln__lte=0))
).distinct()