mirror of
https://github.com/inventree/InvenTree.git
synced 2025-10-24 09:57:40 +00:00
make safer to use with various sanity checks
This commit is contained in:
@@ -14,6 +14,7 @@ from InvenTree.helpers import (
|
|||||||
strip_html_tags,
|
strip_html_tags,
|
||||||
)
|
)
|
||||||
from InvenTree.schema import schema_for_view_output_options
|
from InvenTree.schema import schema_for_view_output_options
|
||||||
|
from InvenTree.serializers import PathScopedMixin
|
||||||
|
|
||||||
|
|
||||||
class CleanMixin:
|
class CleanMixin:
|
||||||
@@ -227,7 +228,15 @@ class OutputOptionsMixin:
|
|||||||
params = self.request.query_params
|
params = self.request.query_params
|
||||||
kwargs.update(self.output_options.format_params(params))
|
kwargs.update(self.output_options.format_params(params))
|
||||||
|
|
||||||
return super().get_serializer(*args, **kwargs)
|
serializer = super().get_serializer(*args, **kwargs)
|
||||||
|
|
||||||
|
# Check if the serializer actually can be filtered - makes not much sense to use this mixin without that prerequisite
|
||||||
|
if not isinstance(serializer, PathScopedMixin):
|
||||||
|
raise Exception(
|
||||||
|
'INVE-W999: `OutputOptionsMixin` can only be used with serializers that contain the `PathScopedMixin` mixin'
|
||||||
|
)
|
||||||
|
|
||||||
|
return serializer
|
||||||
|
|
||||||
|
|
||||||
class SerializerContextMixin:
|
class SerializerContextMixin:
|
||||||
|
|||||||
@@ -39,15 +39,10 @@ class OptFilter:
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize the serializer."""
|
"""Initialize the serializer."""
|
||||||
# Set filterable options for future ref
|
if self.is_filterable is None: # Materialize parameters for later usage
|
||||||
if self.is_filterable is None:
|
|
||||||
self.is_filterable = kwargs.pop('is_filterable', None)
|
self.is_filterable = kwargs.pop('is_filterable', None)
|
||||||
self.is_filterable_vals = kwargs.pop('is_filterable_vals', {})
|
self.is_filterable_vals = kwargs.pop('is_filterable_vals', {})
|
||||||
|
|
||||||
# remove filter args from kwargs
|
|
||||||
# TODO remove: kwargs = PathScopedMixin.gather_filters(self, kwargs)
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
# TODO remove: PathScopedMixin.do_filtering(self, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class PathScopedMixin:
|
class PathScopedMixin:
|
||||||
@@ -86,17 +81,16 @@ class PathScopedMixin:
|
|||||||
tgs_vals[k] = str2bool(val) if isinstance(val, str) else val
|
tgs_vals[k] = str2bool(val) if isinstance(val, str) else val
|
||||||
self.filter_target_values = tgs_vals
|
self.filter_target_values = tgs_vals
|
||||||
|
|
||||||
# TODO remove
|
|
||||||
if len(self.filter_targets) == 0:
|
if len(self.filter_targets) == 0:
|
||||||
raise ValueError('No filter targets found')
|
raise Exception(
|
||||||
|
'INVE-W999: No filter targets found in fields, remove `PathScopedMixin`'
|
||||||
|
)
|
||||||
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def do_filtering(self, *args, **kwargs):
|
def do_filtering(self, *args, **kwargs):
|
||||||
"""Do the actual filtering."""
|
"""Do the actual filtering."""
|
||||||
if InvenTree.ready.isGeneratingSchema() or not hasattr(
|
if not hasattr(self, 'filter_target_values'):
|
||||||
self, 'filter_target_values'
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Throw out fields which are not requested
|
# Throw out fields which are not requested
|
||||||
@@ -109,28 +103,22 @@ class PathScopedMixin:
|
|||||||
# Decorator for marking serialzier fields that can be filtered out
|
# Decorator for marking serialzier fields that can be filtered out
|
||||||
def can_filter(func, default=False, name: Optional[str] = None):
|
def can_filter(func, default=False, name: Optional[str] = None):
|
||||||
"""Decorator for marking serializer fields as filterable."""
|
"""Decorator for marking serializer fields as filterable."""
|
||||||
is_field = False
|
# Ensure this function can be actually filteres
|
||||||
# Check if function is holding OptionalFilterabelSerializer somehow
|
|
||||||
if not issubclass(func.__class__, OptFilter):
|
if not issubclass(func.__class__, OptFilter):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'can_filter can only be applied to OptionalFilterabelSerializer Serializers!'
|
'INVE-W999: `can_filter` can only be applied to serializers that contain `OptFilter` mixin!'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mark the function as filterable
|
# Mark the function as filterable
|
||||||
values = {'default': default, 'name': name if name else func.field_name}
|
func._kwargs['is_filterable'] = True
|
||||||
|
func._kwargs['is_filterable_vals'] = {
|
||||||
if is_field:
|
'default': default,
|
||||||
pass
|
'name': name if name else func.field_name,
|
||||||
# print(func)
|
}
|
||||||
# func.is_filterable = True
|
|
||||||
# func.is_filterable_vals = values
|
|
||||||
else:
|
|
||||||
func._kwargs['is_filterable'] = True
|
|
||||||
func._kwargs['is_filterable_vals'] = values
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
class FilterableListSerializer(OptFilter, serializers.ListSerializer):
|
class FilterableListSerializer(OptFilter, PathScopedMixin, serializers.ListSerializer):
|
||||||
"""Custom ListSerializer which allows filtering of fields."""
|
"""Custom ListSerializer which allows filtering of fields."""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user