Skip to content

Commit 1081333

Browse files
committed
Add queryset
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent fc3cd05 commit 1081333

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 4.2.25 on 2025-12-29 07:48
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("vulnerabilities", "0106_alter_advisoryreference_url_and_more"),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name="advisoryv2",
15+
name="date_imported",
16+
),
17+
]

vulnerabilities/models.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
from django.db import transaction
4343
from django.db.models import Count
4444
from django.db.models import Exists
45+
from django.db.models import F
4546
from django.db.models import OuterRef
47+
from django.db.models import Subquery
4648
from django.db.models import Prefetch
4749
from django.db.models import Q
4850
from django.db.models.functions import Length
@@ -1368,6 +1370,17 @@ def search(query):
13681370
| Q(references__url__icontains=query)
13691371
).distinct()
13701372

1373+
class AdvisoryV2QuerySet(BaseQuerySet):
1374+
def latest_for_avid(self, avid: str):
1375+
return (
1376+
self.filter(avid=avid)
1377+
.order_by(
1378+
F("date_collected").desc(nulls_last=True),
1379+
"-id",
1380+
)
1381+
.first()
1382+
)
1383+
13711384

13721385
# FIXME: Remove when migration from Vulnerability to Advisory is completed
13731386
class Advisory(models.Model):
@@ -2916,9 +2929,6 @@ class AdvisoryV2(models.Model):
29162929
blank=True, null=True, help_text="UTC Date of publication of the advisory"
29172930
)
29182931
date_collected = models.DateTimeField(help_text="UTC Date on which the advisory was collected")
2919-
date_imported = models.DateTimeField(
2920-
blank=True, null=True, help_text="UTC Date on which the advisory was imported"
2921-
)
29222932

29232933
original_advisory_text = models.TextField(
29242934
blank=True,
@@ -2959,11 +2969,15 @@ def risk_score(self):
29592969
risk_score = min(float(self.exploitability * self.weighted_severity), 10.0)
29602970
return round(risk_score, 1)
29612971

2962-
objects = AdvisoryQuerySet.as_manager()
2972+
objects = AdvisoryV2QuerySet.as_manager()
29632973

29642974
class Meta:
29652975
unique_together = ["datasource_id", "advisory_id", "unique_content_id"]
29662976
ordering = ["datasource_id", "advisory_id", "date_published", "unique_content_id"]
2977+
# indexes = models.Index(
2978+
# fields=["avid", "-date_collected", "-id"],
2979+
# name="advisory_latest_by_avid_idx",
2980+
# )
29672981

29682982
def save(self, *args, **kwargs):
29692983
self.full_clean()
@@ -3004,6 +3018,29 @@ def get_aliases(self):
30043018
"""
30053019
return self.aliases.all()
30063020

3021+
def latest_for_avid(self, avid: str):
3022+
return (
3023+
self.filter(avid=avid)
3024+
.order_by(
3025+
F("date_collected").desc(nulls_last=True),
3026+
"-id",
3027+
)
3028+
.first()
3029+
)
3030+
3031+
def latest_per_avid(self):
3032+
latest_ids = (
3033+
AdvisoryV2.objects
3034+
.filter(avid=OuterRef("avid"))
3035+
.order_by(
3036+
F("date_collected").desc(nulls_last=True),
3037+
"-id",
3038+
)
3039+
.values("id")[:1]
3040+
)
3041+
3042+
return self.filter(id=Subquery(latest_ids))
3043+
30073044
alias = get_aliases
30083045

30093046

vulnerabilities/views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from django.urls import reverse_lazy
2424
from django.views import View
2525
from django.views import generic
26+
from django.db.models import F
2627
from django.views.generic.detail import DetailView
2728
from django.views.generic.edit import FormMixin
2829
from django.views.generic.list import ListView
@@ -360,6 +361,15 @@ class AdvisoryDetails(DetailView):
360361
slug_url_kwarg = "avid"
361362
slug_field = "avid"
362363

364+
def get_object(self, queryset=None):
365+
avid = self.kwargs.get(self.slug_url_kwarg)
366+
obj = models.AdvisoryV2.objects.latest_for_avid(avid)
367+
368+
if not obj:
369+
raise Http404("Advisory not found")
370+
371+
return obj
372+
363373
def get_queryset(self):
364374
return (
365375
super()

0 commit comments

Comments
 (0)