Skip to content

Commit 87ffa81

Browse files
authored
Merge pull request #453 from nexB/ui-reduce-queries
Reduce queries in UI
2 parents d7d3206 + c3c9295 commit 87ffa81

4 files changed

Lines changed: 33 additions & 19 deletions

File tree

vulnerabilities/templates/package_update.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ <h1 class="title">
4040
<div class="tags mx-3">
4141
{% for vulnerability in impacted_vuln %}
4242
<span class="tag is-danger is-medium">
43-
<a href="{% url 'vulnerability_view' vulnerability.pk %}" class="has-text-white">{{vulnerability}}</a>
43+
<a href="{% url 'vulnerability_view' vulnerability.pk %}" class="has-text-white">{{vulnerability.vulnerability_id}}</a>
4444
{% if enable_curation %}
4545
<form method="POST" action="{% url 'impacted_package_delete' object.pk vulnerability.pk %}"">
4646
{% csrf_token %}<button class="delete is-small" type="submit"></button>
@@ -74,7 +74,7 @@ <h1 class="title">
7474
<div class="tags mx-3">
7575
{% for vulnerability in resolved_vuln %}
7676
<span class="tag is-primary is-medium">
77-
<a href="{% url 'vulnerability_view' vulnerability.pk %}" class="has-text-white">{{vulnerability}}</a>
77+
<a href="{% url 'vulnerability_view' vulnerability.pk %}" class="has-text-white">{{vulnerability.vulnerability_id}}</a>
7878

7979
{% if enable_curation %}
8080
<form method="POST" action="{% url 'resolved_package_delete' object.pk vulnerability.pk %}">

vulnerabilities/templates/packages.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ <h1 class="title">
4141
</tr>
4242
{% for package in packages %}
4343
<tr>
44-
<td><a href="{% url 'package_view' package.pk %}">{{package}}</a></td>
45-
<td>{{package.vulnerable_to.all|length}}</td>
46-
<td>{{package.resolved_to.all|length}}</td>
44+
<td><a href="{% url 'package_view' package.pk %}">{{package.package_url}}</a></td>
45+
<td>{{package.vulnerability_count}}</td>
46+
<td>{{package.patched_vulnerability_count}}</td>
4747
</tr>
4848
{% endfor %}
4949
</table>

vulnerabilities/templates/vulnerabilities.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ <h1 class="title">
3737
{% for vulnerability in vulnerabilities %}
3838
<tr>
3939
<td><a href="{% url 'vulnerability_view' vulnerability.pk %}">{{vulnerability.vulnerability_id}}</a></td>
40-
<td>{{vulnerability.vulnerable_to.all|length}}</td>
41-
<td>{{vulnerability.resolved_to.all|length}}</td>
40+
<td>{{vulnerability.vulnerable_package_count}}</td>
41+
<td>{{vulnerability.patched_package_count}}</td>
4242
</tr>
4343
{% endfor %}
4444
</table>

vulnerabilities/views.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from urllib.parse import urlencode
2424

2525
from django.core.paginator import Paginator
26+
from django.db.models import Count
2627
from django.http import HttpResponse
2728
from django.shortcuts import render, redirect
2829
from django.urls import reverse
@@ -46,7 +47,7 @@ def get(self, request):
4647

4748
if request.GET:
4849
packages = self.request_to_queryset(request)
49-
result_size = packages.count()
50+
result_size = len(packages)
5051
page_no = int(request.GET.get("page", 1))
5152
packages = Paginator(packages, 50).get_page(page_no)
5253
context["packages"] = packages
@@ -68,9 +69,14 @@ def request_to_queryset(request):
6869
if len(request.GET["name"]):
6970
package_name = request.GET["name"]
7071

71-
return models.Package.objects.all().filter(
72-
name__icontains=package_name,
73-
type__icontains=package_type,
72+
return list(
73+
models.Package.objects.all()
74+
.filter(name__icontains=package_name, type__icontains=package_type)
75+
.annotate(
76+
vulnerability_count=Count("vulnerabilities"),
77+
patched_vulnerability_count=Count("resolved_vulnerabilities"),
78+
)
79+
.prefetch_related()
7480
)
7581

7682

@@ -81,8 +87,8 @@ class VulnerabilitySearchView(View):
8187
def get(self, request):
8288
context = {"form": forms.CVEForm(request.GET or None)}
8389
if request.GET:
84-
vulnerabilities = self.request_to_queryset(request)
85-
result_size = vulnerabilities.count()
90+
vulnerabilities = self.request_to_vulnerabilities(request)
91+
result_size = len(vulnerabilities)
8692
pages = Paginator(vulnerabilities, 50)
8793
vulnerabilities = pages.get_page(int(self.request.GET.get("page", 1)))
8894
context["vulnerabilities"] = vulnerabilities
@@ -91,9 +97,14 @@ def get(self, request):
9197
return render(request, self.template_name, context)
9298

9399
@staticmethod
94-
def request_to_queryset(request):
100+
def request_to_vulnerabilities(request):
95101
vuln_id = request.GET["vuln_id"]
96-
return models.Vulnerability.objects.filter(vulnerability_id__icontains=vuln_id)
102+
return list(
103+
models.Vulnerability.objects.filter(vulnerability_id__icontains=vuln_id).annotate(
104+
vulnerable_package_count=Count("vulnerable_packages"),
105+
patched_package_count=Count("patched_packages"),
106+
)
107+
)
97108

98109

99110
class PackageUpdate(UpdateView):
@@ -112,9 +123,11 @@ def get_context_data(self, **kwargs):
112123
return context
113124

114125
def _package_vulnerabilities(self, package_pk):
115-
116-
resolved_vuln = [i for i in self.get_object().resolved_to]
117-
unresolved_vuln = [i for i in self.get_object().vulnerable_to]
126+
# This can be further optimised by caching get_object result first time it
127+
# is called
128+
package = self.get_object()
129+
resolved_vuln = [i for i in package.resolved_to.values("vulnerability_id", "pk")]
130+
unresolved_vuln = [i for i in package.vulnerable_to.values("vulnerability_id", "pk")]
118131

119132
return resolved_vuln, unresolved_vuln
120133

@@ -214,9 +227,10 @@ def relationship_already_exists(relationship):
214227
@staticmethod
215228
def create_relationship_instance(vulnerability_id, package_id, is_vulnerable):
216229
package = models.Package.objects.get(id=package_id)
230+
# FIXME: Handle the case when vuln_created=True
217231
vulnerability, vuln_created = models.Vulnerability.objects.get_or_create(
218232
vulnerability_id=vulnerability_id
219-
) # nopep8
233+
)
220234
return models.PackageRelatedVulnerability(
221235
vulnerability=vulnerability, package=package, is_vulnerable=is_vulnerable
222236
)

0 commit comments

Comments
 (0)