2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-10-23 17:37:38 +00:00

enable controlling query parameters per field

This commit is contained in:
Matthias Mair
2025-10-18 22:01:33 +02:00
parent 8a178e609e
commit 72286c01ea
2 changed files with 24 additions and 3 deletions

View File

@@ -49,7 +49,10 @@ class FilterableSerializerField:
def enable_filter(
func: Any, default_include: bool = False, filter_name: Optional[str] = None
func: Any,
default_include: bool = False,
filter_name: Optional[str] = None,
filter_by_query: bool = True,
):
"""Decorator for marking a serializer field as filterable.
@@ -59,6 +62,10 @@ def enable_filter(
func: The serializer field to mark as filterable. Will automatically be passed when used as a decorator.
default_include (bool): If True, the field will be included by default unless explicitly excluded. If False, the field will be excluded by default unless explicitly included.
filter_name (str, optional): The name of the filter parameter to use in the URL. If None, the function name of the (decorated) function will be used.
filter_by_query (bool): If True, also look for filter parameters in the request query parameters.
Returns:
The decorated serializer field, marked as filterable.
"""
# Ensure this function can be actually filteres
if not issubclass(func.__class__, FilterableSerializerField):
@@ -71,6 +78,7 @@ def enable_filter(
func._kwargs['is_filterable_vals'] = {
'default': default_include,
'filter_name': filter_name if filter_name else func.field_name,
'filter_by_query': filter_by_query,
}
return func
@@ -129,7 +137,7 @@ class FilterableSerializerMixin:
val = kwargs.pop(pop_ref, poped_kwargs.get(pop_ref))
# Optionally also look in query parameters
if val is None and self.filter_on_query:
if val is None and self.filter_on_query and v.get('filter_by_query', True):
val = query_params.pop(pop_ref, None)
if isinstance(val, list) and len(val) == 1:
val = val[0]

View File

@@ -22,7 +22,7 @@ class SampleSerializer(
"""Meta options."""
model = User
fields = ['field_a', 'field_b', 'field_c', 'field_d', 'id']
fields = ['field_a', 'field_b', 'field_c', 'field_d', 'field_e', 'id']
field_a = SerializerMethodField(method_name='sample')
field_b = InvenTree.serializers.enable_filter(
@@ -38,6 +38,11 @@ class SampleSerializer(
True,
filter_name='crazy_name',
)
field_e = InvenTree.serializers.enable_filter(
InvenTree.serializers.FilterableSerializerMethodField(method_name='sample'),
filter_name='field_e',
filter_by_query=False,
)
def sample(self, obj):
"""Sample method field."""
@@ -94,6 +99,14 @@ class FilteredSerializers(InvenTreeAPITestCase):
self.assertNotContains(response, 'field_c')
self.assertNotContains(response, 'field_d')
# Query parameters being turned off means it should not be enable-able
response = self.client.get(url, {'field_e': True})
self.assertContains(response, 'field_a')
self.assertNotContains(response, 'field_b')
self.assertContains(response, 'field_c')
self.assertContains(response, 'field_d')
self.assertNotContains(response, 'field_e')
def test_failiure_enable_filter(self):
"""Test sanity check for enable_filter."""
# Allowed usage