@@ -1139,9 +1139,9 @@ def get_affecting_vulnerabilities(self):
11391139 next_fixed_package_vulns = list (fixed_by_pkg .affected_by )
11401140
11411141 fixed_by_package_details ["fixed_by_purl" ] = fixed_by_purl
1142- fixed_by_package_details ["fixed_by_purl_vulnerabilities" ] = (
1143- next_fixed_package_vulns
1144- )
1142+ fixed_by_package_details [
1143+ "fixed_by_purl_vulnerabilities"
1144+ ] = next_fixed_package_vulns
11451145 fixed_by_pkgs .append (fixed_by_package_details )
11461146
11471147 vuln_details ["fixed_by_package_details" ] = fixed_by_pkgs
@@ -2865,11 +2865,7 @@ def latest_for_avid(self, avid: str):
28652865 )
28662866
28672867 def latest_per_avid (self ):
2868- return self .order_by (
2869- "avid" ,
2870- F ("date_collected" ).desc (nulls_last = True ),
2871- "-id" ,
2872- ).distinct ("avid" )
2868+ return self .filter (is_latest = True )
28732869
28742870 def latest_for_avids (self , avids ):
28752871 return self .filter (avid__in = avids ).latest_per_avid ()
@@ -2941,6 +2937,12 @@ def latest_advisories_for_purl(self, purl):
29412937 qs = self .filter (id__in = Subquery (adv_ids ))
29422938 return qs .latest_per_avid ()
29432939
2940+ def todo_excluded (self ):
2941+ """Exclude advisory ineligible for ToDo computation."""
2942+ from vulnerabilities .importers import TODO_EXCLUDED_PIPELINES
2943+
2944+ return self .exclude (datasource_id__in = TODO_EXCLUDED_PIPELINES )
2945+
29442946
29452947class AdvisorySet (models .Model ):
29462948
@@ -2986,6 +2988,7 @@ class AdvisoryV2(models.Model):
29862988 max_length = 200 ,
29872989 blank = False ,
29882990 null = False ,
2991+ db_index = True ,
29892992 help_text = "Unique ID for the datasource used for this advisory ." "e.g.: nginx_importer_v2" ,
29902993 )
29912994
@@ -3069,6 +3072,14 @@ class AdvisoryV2(models.Model):
30693072 help_text = "UTC Date on which the advisory was collected" ,
30703073 )
30713074
3075+ is_latest = models .BooleanField (
3076+ default = False ,
3077+ blank = False ,
3078+ null = False ,
3079+ db_index = True ,
3080+ help_text = "Indicates whether this is the latest version of the advisory identified by its AVID." ,
3081+ )
3082+
30723083 original_advisory_text = models .TextField (
30733084 blank = True ,
30743085 null = True ,
@@ -3121,6 +3132,11 @@ class AdvisoryV2(models.Model):
31213132 class Meta :
31223133 unique_together = ["datasource_id" , "advisory_id" , "unique_content_id" ]
31233134 ordering = ["datasource_id" , "advisory_id" , "date_published" , "unique_content_id" ]
3135+ constraints = [
3136+ models .UniqueConstraint (
3137+ fields = ["avid" ], condition = Q (is_latest = True ), name = "unique_latest_per_avid"
3138+ )
3139+ ]
31243140 indexes = [
31253141 models .Index (
31263142 fields = ["avid" , "-date_collected" , "-id" ],
0 commit comments