Skip to content

Conversation

@Jincxz
Copy link
Contributor

@Jincxz Jincxz commented Nov 19, 2025

This PR adds "in" filters for CharFilter and ChoiceFilter fields in the API views (not including the V1 API endpoints). The new filters can be accessed via the "in" lookup (e.g. {field_name}__in=A,B).

Closes OSIDB-4588

@Jincxz Jincxz requested a review from a team November 19, 2025 21:03
@Jincxz Jincxz changed the title Add in filter for API views [OSIDB-4588] Add in filter for API views Nov 19, 2025
Copy link
Contributor

@osoukup osoukup left a comment

Choose a reason for hiding this comment

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

LGTM. Just out of curiosity, what would happen when a user runs a query like

...?impact=LOW&impact__in=LOW,MODERATE

which is stupid but possible. Both filter apply or somehow interfere?

@JakubFrejlach
Copy link
Contributor

LGTM. Just out of curiosity, what would happen when a user runs a query like

...?impact=LOW&impact__in=LOW,MODERATE

which is stupid but possible. Both filter apply or somehow interfere?

They are different query parameters, so they should be applied in AND manner

Copy link
Contributor

@JakubFrejlach JakubFrejlach left a comment

Choose a reason for hiding this comment

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

Some changes needed, but overall looking good.

Comment on lines 351 to 378
def test_in_filter_with_uuid_fields(self, auth_client, test_api_v2_uri):
"""Test that UUID fields work with auto-in filter"""
flaw1 = FlawFactory(embargoed=False)
flaw2 = FlawFactory(embargoed=False)
affect1 = AffectFactory(flaw=flaw1)
affect2 = AffectFactory(flaw=flaw2)

# Test filtering by single UUID first
response = auth_client().get(f"{test_api_v2_uri}/affects?uuid={affect1.uuid}")
assert response.status_code == status.HTTP_200_OK
assert response.json()["count"] == 1

# Test filtering by multiple UUIDs with __in suffix
response = auth_client().get(
f"{test_api_v2_uri}/affects?uuid__in={affect1.uuid},{affect2.uuid}"
)
assert response.status_code == status.HTTP_200_OK
results = response.json()["results"]
assert len(results) == 2
uuids = {r["uuid"] for r in results}
assert uuids == {str(affect1.uuid), str(affect2.uuid)}
Copy link
Contributor

Choose a reason for hiding this comment

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

there is currently no filter uuid__in because the InFilterSet creates matching in filters only for CharFilter or ChoiceFilter whereas uuid uses UUIDFilter. This test succeeds because since there is no uuid__in filter defined, supplying the uuid__in query parameter has no affect and the query simply returns all affects and since there are total 2 affects in this test case, the assert len(results) == 2 actually passes.

f"{test_api_v2_uri}/affects?flaw__source__in=INTERNET,CUSTOMER"
)
assert response.status_code == status.HTTP_200_OK
assert response.json()["count"] == 2
Copy link
Contributor

Choose a reason for hiding this comment

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

This test has in total 2 affects and the assert checks for existence of 2 affects, I would add one more affect with different Flaw source to really test whether the filter is applied.

Comment on lines +9423 to +9618
- in: query
name: affects__affectedness__in
schema:
type: array
items:
type: string
enum:
- ''
- AFFECTED
- NEW
- NOTAFFECTED
description: |+
Multiple values may be separated by commas.
explode: false
style: form
Copy link
Contributor

Choose a reason for hiding this comment

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

some of the new in filters has allowed empty values, how would passing that in the in filter work? 🤔 Do we want to/need to support it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like we can just query for the empty values by leaving the space in the comma separation empty (e.g. affects?affectedness__in=,AFFECTED). I have added some tests for this.

Comment on lines 1655 to 1673
"uuid": ["exact"],
"name": ["exact"],
"affiliation": ["exact"],
"from_upstream": ["exact"],
"created_dt": ["exact"]
+ LT_GT_LOOKUP_EXPRS
+ LTE_GTE_LOOKUP_EXPRS
Copy link
Member

@MrMarble MrMarble Nov 20, 2025

Choose a reason for hiding this comment

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

One question, why not just pass in in this array?
Is part of the documentation https://django-filter.readthedocs.io/en/stable/guide/usage.html#generating-filters-with-meta-fields

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had initially considered that but it was a bit of manually tracking so I programmatically added the fields instead (just in case I would end up missing some).

@Jincxz Jincxz force-pushed the OSIDB-4588-in-filter branch from 709f307 to 1d55c89 Compare November 20, 2025 17:02
@Jincxz Jincxz force-pushed the OSIDB-4588-in-filter branch from 1d55c89 to 30b369b Compare November 20, 2025 17:06
@Jincxz Jincxz requested a review from JakubFrejlach November 20, 2025 17:07
@Jincxz
Copy link
Contributor Author

Jincxz commented Nov 20, 2025

LGTM. Just out of curiosity, what would happen when a user runs a query like

...?impact=LOW&impact__in=LOW,MODERATE

which is stupid but possible. Both filter apply or somehow interfere?

They are different query parameters, so they should be applied in AND manner

Did some testing and it does look like a query like ...?impact=LOW&impact__in=LOW,MODERATE will perform an AND and, in this case, essentially just be ...?impact=LOW.

@osoukup
Copy link
Contributor

osoukup commented Nov 21, 2025

LGTM. Just out of curiosity, what would happen when a user runs a query like

...?impact=LOW&impact__in=LOW,MODERATE

which is stupid but possible. Both filter apply or somehow interfere?

They are different query parameters, so they should be applied in AND manner

Did some testing and it does look like a query like ...?impact=LOW&impact__in=LOW,MODERATE will perform an AND and, in this case, essentially just be ...?impact=LOW.

That sounds like a desired behavior. Thank you for testing it!

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.

5 participants