Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fixed packages in packages endpoint #784

Merged
merged 6 commits into from
Jul 4, 2022

Conversation

TG1999
Copy link
Contributor

@TG1999 TG1999 commented Jun 27, 2022

Signed-off-by: Tushar Goel [email protected]

@TG1999 TG1999 linked an issue Jun 27, 2022 that may be closed by this pull request
Copy link
Contributor

@tdruez tdruez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TG1999 The new code looks fine.
You should add a simple unit test for the fixed_packages property.
Model properties should be easy to test and you should always add a unit test when you add new properties.

Copy link
Contributor

@tdruez tdruez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TG1999 Your code is not tested. How can we know it works?

Comment on lines 55 to 64
params = self.context["request"].query_params
name = params.get("name")
if name:
data = data.filter(name=name)
namespace = params.get("namespace")
if namespace:
data = data.filter(namespace=namespace)
type = params.get("type")
if type:
data = data.filter(type=type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using proper filters instead of this duplicated logic?

fields = ["url", "vulnerability_id"]


class MinimalPackageSerializerWithFixedVulnerabilities(serializers.HyperlinkedModelSerializer):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class name is too long thus not readable.

@TG1999 TG1999 marked this pull request as draft June 28, 2022 13:17
@TG1999 TG1999 requested a review from tdruez June 29, 2022 14:37
@TG1999 TG1999 marked this pull request as ready for review June 29, 2022 14:38
Comment on lines 227 to 246
def get_queryset(self):
params = self.request.query_params
query = Q()
name = params.get("name")
if name:
query &= Q(name=name)
namespace = params.get("namespace")
if namespace:
query &= Q(namespace=namespace)
type = params.get("type")
if type:
query &= Q(type=type)
queryset = Vulnerability.objects.prefetch_related(
Prefetch(
"packages",
queryset=Package.objects.filter(query, packagerelatedvulnerability__fix=True),
to_attr="filtered_fixed_packages",
)
)
return queryset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still duplicated code and much harder to read and understand than the previous code.
This is not what I meant by "proper filters" but I was rather referring to https://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend.
Any reason to not use a FilterSet here?

Copy link
Contributor Author

@TG1999 TG1999 Jun 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filters applied by me are for Package model and the viewset is on Vulnerabilities model

Copy link
Contributor

@tdruez tdruez Jun 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but relational fields are not available on FilterSet?

Copy link
Contributor Author

@TG1999 TG1999 Jun 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do something like this https://github.com/philipn/django-rest-framework-filters#filtering-across-relationships, but the query will then look like api?package__name=name not api?name=name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api?package__name=name

Is it a problem?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TG1999 you already defined a PackageFilterSet, you should use it, for example:

class VulnerabilityViewSet(viewsets.ReadOnlyModelViewSet):
    def get_fixed_packages_qs(self):
        package_filter_data = {"packagerelatedvulnerability__fix": True}

        query_params = self.request.query_params
        for field_name in ["name", "namespace", "type"]:
            value = query_params.get(field_name)
            if value:
                package_filter_data[field_name] = value

        return PackageFilterSet(package_filter_data).qs

    def get_queryset(self):
        queryset = Vulnerability.objects.prefetch_related(
            Prefetch(
                "packages",
                queryset=self.get_fixed_packages_qs(),
                to_attr="filtered_fixed_packages",
            )
        )
        return queryset

Also, make sure to add packagerelatedvulnerability__fix to the PackageFilterSet.fields.

Lastly, you should always document such methods using the docstring, it is not obvious to the reader what is happening here and why we are prefetching filtered package data.

@TG1999 TG1999 force-pushed the api_fixed_packages branch 2 times, most recently from 13aa93f to 9fd88d0 Compare July 4, 2022 16:43
Signed-off-by: Tushar Goel <[email protected]>
@TG1999 TG1999 merged commit 49052d6 into aboutcode-org:main Jul 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add fixed_packages in packages endpoint
2 participants