|
17 | 17 |
|
18 | 18 | from django.contrib import messages |
19 | 19 | from django.contrib.auth.decorators import login_required |
20 | | -from django.db.models import Count, Q |
| 20 | +from django.db.models import Count, Q, OuterRef, Subquery, IntegerField |
21 | 21 | from django.shortcuts import get_object_or_404, redirect, render |
22 | 22 | from django.urls import reverse |
23 | 23 | from django_filters import rest_framework as filters |
@@ -76,11 +76,45 @@ def _get_filtered_hosts(filter_params): |
76 | 76 |
|
77 | 77 | @login_required |
78 | 78 | def host_list(request): |
| 79 | + # Pre-compute security updates, bug updates, errata and packages for speed |
| 80 | + sec_updates_sq = Subquery( |
| 81 | + Host.updates.through.objects.filter( |
| 82 | + host_id=OuterRef("pk"), packageupdate__security=True |
| 83 | + ) |
| 84 | + .values("host_id") |
| 85 | + .annotate(c=Count("packageupdate_id", distinct=True)) |
| 86 | + .values("c"), |
| 87 | + output_field=IntegerField(), |
| 88 | + ) |
| 89 | + bug_updates_sq = Subquery( |
| 90 | + Host.updates.through.objects.filter( |
| 91 | + host_id=OuterRef("pk"), packageupdate__security=False |
| 92 | + ) |
| 93 | + .values("host_id") |
| 94 | + .annotate(c=Count("packageupdate_id", distinct=True)) |
| 95 | + .values("c"), |
| 96 | + output_field=IntegerField(), |
| 97 | + ) |
| 98 | + errata_sq = Subquery( |
| 99 | + Host.errata.through.objects.filter(host_id=OuterRef("pk")) |
| 100 | + .values("host_id") |
| 101 | + .annotate(c=Count("erratum_id", distinct=True)) |
| 102 | + .values("c"), |
| 103 | + output_field=IntegerField(), |
| 104 | + ) |
| 105 | + packages_sq = Subquery( |
| 106 | + Host.packages.through.objects.filter(host_id=OuterRef("pk")) |
| 107 | + .values("host_id") |
| 108 | + .annotate(c=Count("package_id", distinct=True)) |
| 109 | + .values("c"), |
| 110 | + output_field=IntegerField(), |
| 111 | + ) |
| 112 | + |
79 | 113 | hosts = Host.objects.select_related().annotate( |
80 | | - sec_updates_count=Count('updates', filter=Q(updates__security=True), distinct=True), |
81 | | - bug_updates_count=Count('updates', filter=Q(updates__security=False), distinct=True), |
82 | | - errata_count=Count('errata', distinct=True), |
83 | | - packages_count=Count('packages', distinct=True), |
| 114 | + sec_updates_count=sec_updates_sq, |
| 115 | + bug_updates_count=bug_updates_sq, |
| 116 | + errata_count=errata_sq, |
| 117 | + packages_count=packages_sq, |
84 | 118 | ) |
85 | 119 |
|
86 | 120 | if 'domain_id' in request.GET: |
|
0 commit comments