99
1010from urllib .parse import unquote
1111
12+ from django .db .models import Prefetch
13+ from django .db .models import Q
1214from django_filters import rest_framework as filters
1315from packageurl import PackageURL
1416from rest_framework import serializers
@@ -50,34 +52,7 @@ class Meta:
5052 fields = ["url" , "purl" ]
5153
5254
53- class FilteredPackageListSerializer (serializers .ListSerializer ):
54- def to_representation (self , data ):
55- params = self .context ["request" ].query_params
56- name = params .get ("name" )
57- if name :
58- data = data .filter (name = name )
59- namespace = params .get ("namespace" )
60- if namespace :
61- data = data .filter (namespace = namespace )
62- type = params .get ("type" )
63- if type :
64- data = data .filter (type = type )
65- return super (FilteredPackageListSerializer , self ).to_representation (data )
66-
67-
68- class FixedPackageSerializer (serializers .ModelSerializer ):
69-
70- purl = serializers .CharField (source = "package_url" )
71-
72- class Meta :
73- list_serializer_class = FilteredPackageListSerializer
74- model = Package
75- fields = ["url" , "purl" ]
76-
77-
78- class MinimalVulnerabilitySerializerWithReferencesAndSummary (
79- serializers .HyperlinkedModelSerializer
80- ):
55+ class VulnSerializerRefsAndSummary (serializers .HyperlinkedModelSerializer ):
8156 """
8257 Used for nesting inside package focused APIs.
8358 """
@@ -99,7 +74,7 @@ class Meta:
9974 fields = ["url" , "vulnerability_id" ]
10075
10176
102- class MinimalPackageSerializerWithFixedVulnerabilities (serializers .HyperlinkedModelSerializer ):
77+ class PackageSerializerFixedVulns (serializers .HyperlinkedModelSerializer ):
10378 """
10479 Used for nesting inside vulnerability focused APIs.
10580 """
@@ -126,7 +101,9 @@ class Meta:
126101
127102class VulnerabilitySerializer (serializers .HyperlinkedModelSerializer ):
128103
129- fixed_packages = FixedPackageSerializer (many = True , source = "resolved_to" , read_only = True )
104+ fixed_packages = MinimalPackageSerializer (
105+ many = True , source = "filtered_fixed_packages" , read_only = True
106+ )
130107 affected_packages = MinimalPackageSerializer (many = True , source = "vulnerable_to" , read_only = True )
131108
132109 references = VulnerabilityReferenceSerializer (many = True , source = "vulnerabilityreference_set" )
@@ -152,13 +129,13 @@ def to_representation(self, instance):
152129 return data
153130
154131 purl = serializers .CharField (source = "package_url" )
155- affected_by_vulnerabilities = MinimalVulnerabilitySerializerWithReferencesAndSummary (
132+ affected_by_vulnerabilities = VulnSerializerRefsAndSummary (
156133 many = True , source = "vulnerable_to" , read_only = True
157134 )
158- fixing_vulnerabilities = MinimalVulnerabilitySerializerWithReferencesAndSummary (
135+ fixing_vulnerabilities = VulnSerializerRefsAndSummary (
159136 many = True , source = "resolved_to" , read_only = True
160137 )
161- fixed_packages = MinimalPackageSerializerWithFixedVulnerabilities (many = True , read_only = True )
138+ fixed_packages = PackageSerializerFixedVulns (many = True , read_only = True )
162139
163140 class Meta :
164141 model = Package
@@ -247,7 +224,27 @@ class Meta:
247224
248225
249226class VulnerabilityViewSet (viewsets .ReadOnlyModelViewSet ):
250- queryset = Vulnerability .objects .all ()
227+ def get_queryset (self ):
228+ params = self .request .query_params
229+ query = Q ()
230+ name = params .get ("name" )
231+ if name :
232+ query &= Q (name = name )
233+ namespace = params .get ("namespace" )
234+ if namespace :
235+ query &= Q (namespace = namespace )
236+ type = params .get ("type" )
237+ if type :
238+ query &= Q (type = type )
239+ queryset = Vulnerability .objects .prefetch_related (
240+ Prefetch (
241+ "packages" ,
242+ queryset = Package .objects .filter (query , packagerelatedvulnerability__fix = True ),
243+ to_attr = "filtered_fixed_packages" ,
244+ )
245+ )
246+ return queryset
247+
251248 serializer_class = VulnerabilitySerializer
252249 paginate_by = 50
253250 filter_backends = (filters .DjangoFilterBackend ,)
0 commit comments