python - Django 查询集获取行值作为列名

标签 python django django-models django-views

这些是我的模型:

class Build(models.Model):
    name = models.CharField(db_index=True, max_length=56)
    description = models.TextField(max_length=512, null=True, blank=True)


class Case(models.Model):
    name = models.CharField(db_index=True, max_length=255)
    description = models.TextField(max_length=1024, null=True, blank=True)


class Result(models.Model):
    status = models.CharField(max_length=12)
    result_build = models.ForeignKey(Build, related_name='result_build', on_delete=models.CASCADE)
    result_case = models.ForeignKey(Case, related_name='result_case', on_delete=models.CASCADE)

我需要一个 django QuerySet 来获取如下数据:

....................................................
: case_name : case_description : build_X : build_Y :
:...........:..................:.........:.........:
:  test1    :   case1          :  PASS   :  FAIL   :
:  test2    :   case2          :  FAIL   :  PASS   :
:...........:..................:.........:.........:

其中 case_namecase_descriptionCase 模型中的字段。

build_X 和 build_Y 是 Build 模型中可用的两个构建名称 PASS 和 FAIL 是不同案例的状态,并根据 Result 模型构建。

最佳答案

这是使用直通模型进行多对多关系的经典案例。模型类可以重构如下:

class Build(models.Model):
    name = models.CharField(db_index=True, max_length=56)
    description = models.TextField(max_length=512, null=True, blank=True)


class Case(models.Model):
    name = models.CharField(db_index=True, max_length=255)
    description = models.TextField(max_length=1024, null=True, blank=True)
    builds = models.ManyToManyField('Build', through='Result', related_name='cases')


class Result(models.Model):
    status = models.CharField(max_length=12)
    build = models.ForeignKey('Build', on_delete=models.CASCADE)
    case = models.ForeignKey('Case', on_delete=models.CASCADE)

我们还可以简单地调用 Result 的属性 buildcase,而无需名称冗余。尽管 lated_name 并不麻烦,但我们在这里并不真正需要它。

现在您可以使用 m2m 关系来查询您的模型:

case = Case.objects.get(pk=1) # get Case object with primary key 1
case.builds.all() # get all Build objects related to case
build = Build.objects.get(pk=1) # get Build object with primary key 1
build.cases.all() # get all Case objects related to build
# UPDATE
# get Result objects for the "case" with pk=1 retrieved before
results = Result.objects.filter(case=case)
# output each entry as row with all property values
for r in results:
    print(r.case.name, r.case.description, r.build.name, r.build, description, r.status)

您还可以使用.filter来缩小查询结果范围。

编辑:

这是创建矩阵表的一种可能方法。这是您可以放入 View 中的代码:

cases = Case.objects.all()
builds = Build.objects.all()
matrix = []
for c in cases:
    result = {}
    result['case'] = c
    result['status'] = []
    for b in builds:
        result['status'].append(Result.objects.filter(
                                    case=c,
                                    build=b
                               ).values_list('status', flat=True))
    matrix.append(result)

现在您应该有一个包含每种情况的字典的表。将 buildsmatrix 作为上下文传递给模板。然后,您可以迭代 builds 以创建表标题(请注意在开头留出一两列空间以列出案例)。然后迭代矩阵并创建表体。首先获取第一列(或前两列)的 case,然后输出 status

我希望这能为您指明方向。一旦获得正确的结果,您就可以进一步优化性能。

编辑2:

这是表格的示例。
将上面代码片段中的 buildsmatrix 作为上下文传递给模板:

<table>
  <tr>
    <th>Case name</th>
    <th>Case description</th>
    {% for b in builds %}
      <th>{{ b.name }}</th>
    {% endfor %}
  </tr>
  {% for row in matrix %}
    <tr>
      <td>{{ row.case.name }}</td>
      <td>{{ row.case.description }}</td>
      {% for s in row.status %}
        <td>{{ s.0 }}</td>
      {% endfor %}
    </tr>
  {% endfor %}
</table>

在第一个 for 循环中,我们创建一个表标题,其中包含两个用于案例名称和案例描述的列标题,以及一个用于每个构建的列标题。
在第二个 for 循环中,我们为每种情况创建一个表行。在嵌套循环中,我们输出状态。

这是一种非常简单的方法,可能可以进一步优化,但我将其留给您。

关于python - Django 查询集获取行值作为列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48506031/

相关文章:

python - 基于另一列 str 的条件字符串分割 Python

python - 为什么 ... == True 在 Python 3 中返回 False?

定义状态常量的 Pythonic 方式

python - Django 如何读取http请求并发送http响应

django - 插入数据库 MySQL Django

python - Django ContentFile get_available_name() 得到了一个意外的关键字参数 'max_length'

python - Google 日历 API 与 Python 集成 - 在日历 API 中更改发件人的邮件地址

python - 如何混淆 jinja2 中变量中的数据?例如变量 = "John Smith",我想要类似 "Odsv Wgtvs"的东西

django - 如何创建基于 Django 中的单个条件过滤多个字段的查询集?

django - Django 测试用例中的 IntegrityError