Django Orm выбрать из случая, когда - PullRequest
0 голосов
/ 11 мая 2018

Я хочу получить некоторые данные из подзапроса через Django ORM. вот мой исключенный SQL

SELECT "risk_level", COUNT("t"."id") 
FROM(
    SELECT 
        "task_taskreport"."id" as "id",
    CASE
       WHEN MAX("task_vuln"."severity_points") >= 8.0 THEN 'high'
       WHEN (MAX("task_vuln"."severity_points") >= 5.0 AND MAX("task_vuln"."severity_points") <= 7.0) THEN 'middle'
       WHEN (MAX("task_vuln"."severity_points") >= 2.0 AND MAX("task_vuln"."severity_points") <= 4.0) THEN 'low'
       WHEN MAX("task_vuln"."severity_points") <= 1.0 THEN 'none'
      ELSE NULL
   END AS "risk_level"
   FROM "task_taskreport"
   LEFT OUTER JOIN "task_taskreport_vuln" ON ("task_taskreport"."id" = 
   "task_taskreport_vuln"."task_report_id")
   LEFT OUTER JOIN "task_vuln" ON ("task_taskreport_vuln"."vuln_id" = "task_vuln"."vul_id")
   WHERE "task_taskreport"."subtask_id" = 21
   GROUP BY "task_taskreport"."id" ORDER BY "task_taskreport"."id" DESC) as t 
   group by "risk_level";

Я пробовал это

TaskReport.objects.filter(subtask__pk=self.pk).\
            annotate(max_points=Max('vulns__severity_points')).annotate(
            risk_level=Case(
                When(max_points__gte=8, then=Value('high')),
                When(max_points__gte=5, max_points__lte=7, then=Value('middle')),
                When(max_points__gte=2, max_points__lte=4, then=Value('low')),
                When(max_points__lte=1, then=Value('none')),
                output_field=models.CharField(),
            )
        ).values('risk_level', 'pk').annotate(count=Count('risk_level'))

но это выдает исключение

django.core.exceptions.FieldError: Cannot compute Count('risk_level'): 'risk_level' is an aggregate

1 Ответ

0 голосов
/ 11 мая 2018

Если у вас сложный SQL-запрос, который выполняет именно то, что вы хотите, вы можете выполнить необработанный SQL-запрос в Django и использовать его в качестве QuerySet.

Вот пример из этогостраница документации Django:

>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
...     print(p)
John Smith
Jane Jones
...