【问题标题】:Aggregation on 'one to many' for matrix view in DjangoDjango中矩阵视图的“一对多”聚合
【发布时间】:2018-02-19 04:28:15
【问题描述】:

我有两张如下表。

这些是“一个(History.testinoid)到多个(Result.testinoid)”的关系。 (结果表为外部数据库)

class History(models.Model): # default database
    idx = models.AutoField(primary_key=True)
    scenario_id = models.ForeignKey(Scenario)
    executor = models.CharField(max_length=255)
    createdate = models.DateTimeField() 
    testinfoid = models.IntegerField(unique=True) 

class Result(models.Model):  # external (Result.objects.using('external'))
    idx = models.AutoField(primary_key=True) 
    testinfoid = models.ForeignKey(History, to_field='testinfoid', related_name='result')
    testresult = models.CharField(max_length=10)

    class Meta:
        unique_together = (('idx', 'testinfoid'),)

所以,我想通过 Result 表中的 'testresult' 字段来表示计数。

它有一些条件,例如“通过”或“失败”。

我想为每个条件表达一个计数查询集。像这样。

[{'idx': 1, 'pass_count': 10, 'fail_count': 5, 'executor': '某人', ...} ...
...
{'idx': 10, 'pass_count': 1, 'fail_count': 10, 'executor': '某人', ...}]

有可能吗?

【问题讨论】:

标签: django orm django-queryset


【解决方案1】:

这是一个两级聚合,其中第二级应显示为表格列 - “矩阵视图”。

A) 使用 Python 循环 的解决方案,通过二级(“测试结果”)创建带有注释的列。

from django.db.models import Count
from collections import OrderedDict


qs = (History.objects
      .values('pk', 'executor', 'testinfoid',... 'result__testresult')
      .annotate(result_count=Count('pk'))
      )
qs = qs.filter(...).order_by(...)

data = OrderedDict()
count_columns = ('pass_count', 'fail_count', 'error_count',
                 'expected_failure_count', 'unexpected_success_count')
for row in qs:
    data.setdefault(row.pk, dict.fromkeys(count_columns, 0)).update(
        {(k if k != result_count else row['result__testresult'] + '_count'): v
         for k, v in row_items()
         if k != 'result__testresult'
         }
    )
out = list(data.values())

OrderedDict 类用于保存order_by()

B) 使用 Django 1.11+ 中的子查询 的解决方案(如果结果应该是一个查询集。例如,通过单击最终在管理员视图中进行排序或过滤,以及如果可以接受更复杂的查询并且*_count 的列数非常低。)。我可以用子查询编写一个解决方案,但我不确定查询是否会在不同的数据库后端足够快。也许其他人的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2021-03-04
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多