【问题标题】:How to avoid duplicate values from queryset如何避免查询集中的重复值
【发布时间】:2021-03-25 09:19:26
【问题描述】:

我有三个模型

class Records(Model):

    plan = models.ForeignKey(Plan, on_delete=models.CASCADE,
                              related_name="records_plan", null=True)
    observation = models.CharField(max_length=255, blank=True)
    description = models.TextField(null=True, blank=True)
    rating = models.CharField(max_length=255, blank=True)

class Plan(Model):
    plan_title = models.CharField(max_length=255, blank=True)
    plan_size = models.ForeignKey(Size, on_delete=models.CASCADE,
                              related_name="%(class)s_size", null=True)
    description = models.TextField(null=True, blank=True)


class Size(Model):
    value = models.CharField(max_length=255, blank=True)
    order = models.CharField(max_length=255, blank=True)

在此我需要根据计划的大小绘制计划图表

我的初始查询集是

qs = Plan.objects.values('plan_size__value').annotate(
    count=Count('plan_size__value'),
).order_by("-plan_size__order").distinct()

使用这个查询我可以得到一个带有数据和字段的查询集

我想在代码的后期应用过滤器的相同查询集

qs =  qs.filter(records_plan__rating = 'low')

在这种情况下,我得到了输出,但是值是重复的(例如,如果一个计划有两个记录,我的图表需要将其视为一个计划,但这里它是两个计划),如何解决这个问题

或者如何在使用记录模型过滤计划时获得计划的独特价值

【问题讨论】:

  • .annotate(..)Size 模型不是更有意义吗?
  • 是的,标注plan_size__value plan_size是Plan模型到Size模型的外键字段名,Size模型值是Size模型中的值

标签: django django-views django-orm


【解决方案1】:

您正在为 order_by 使用 plan_size__order 字段,并且在该字段上实现了 distinct()。稍后您将使用其他字段records_plan__rating 进行过滤。所以这里你需要为records_plan__rating 明确指定distinct() 以获得不同的结果。

【讨论】:

  • 您能帮我查询一下吗
  • qs = qs.filter(records_plan__rating = 'low').distinct('records_plan__rating') 这可能会解决您的问题。
  • 这仅适用于 postgres sl ,我正在使用我的 sql
【解决方案2】:

你可能应该注释你的 Size 对象,而不是 Plan 对象:

Size.object.filter(
    plan__records_plan__rating='low'
).annotate(
    number_of_plans=Count('plan', distinct=True)
).order_by('order')

由此产生的Size 对象将具有一个额外的属性.number_of_plans,其中包含与该Size 相关的Plans 的数量。

distinct=True 是必要的,如果您不想计算每个计划 per 低评级。例如,如果一个Plan 有五个Records 并且三个有低评级,distinct=True,我们仍然计算没有distinct=True 的那个计划一次,我们将计算这个3 次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    相关资源
    最近更新 更多