diff --git a/src/backend/InvenTree/part/api.py b/src/backend/InvenTree/part/api.py index b0ffd224b0..1eb603dd7c 100644 --- a/src/backend/InvenTree/part/api.py +++ b/src/backend/InvenTree/part/api.py @@ -310,19 +310,13 @@ class CategoryTree(TreeMixin, ListAPI): model_class = PartCategory queryset = PartCategory.objects.all() - serializer_class = part_serializers.CategoryTree + serializer_class = part_serializers.CategoryTreeSerializer filterset_class = CategoryTreeFilter def get_queryset(self, *args, **kwargs): """Return an annotated queryset for the CategoryTree endpoint.""" queryset = super().get_queryset(*args, **kwargs) - queryset = part_serializers.CategoryTree.annotate_queryset(queryset) - return queryset - - def filter_queryset(self, queryset): - """Filter the queryset, and include all ancestors of matched items when searching.""" - queryset = super().filter_queryset(queryset) - queryset = part_serializers.CategoryTree.annotate_queryset(queryset) + queryset = part_serializers.CategoryTreeSerializer.annotate_queryset(queryset) return queryset diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index 57244acf3f..a9a87c7e80 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -181,7 +181,7 @@ class CategorySerializer( parameters = common.filters.enable_parameters_filter() -class CategoryTree(InvenTree.serializers.InvenTreeModelSerializer): +class CategoryTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer): """Serializer for PartCategory tree.""" class Meta: diff --git a/src/backend/InvenTree/stock/api.py b/src/backend/InvenTree/stock/api.py index 448477782d..31ef0f915a 100644 --- a/src/backend/InvenTree/stock/api.py +++ b/src/backend/InvenTree/stock/api.py @@ -33,11 +33,11 @@ from InvenTree.api import ( BulkCreateMixin, BulkUpdateMixin, ListCreateDestroyAPIView, + TreeMixin, meta_path, ) from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( - ORDER_FILTER, SEARCH_ORDER_FILTER, InvenTreeDateFilter, NumberOrNullFilter, @@ -455,20 +455,33 @@ class StockLocationDetail( ) -class StockLocationTree(ListAPI): +class LocationTreeFilter(FilterSet): + """Custom filterset class for the StockLocationTree endpoint.""" + + class Meta: + """Metaclass options for this filterset.""" + + model = StockLocation + fields = ['parent', 'tree_id', 'level'] + + max_level = rest_filters.NumberFilter( + label=_('Max Level'), + method='filter_max_level', + help_text=_('Limit the depth of the category tree'), + ) + + def filter_max_level(self, queryset, name, value): + """Filter by the maximum depth of the category tree.""" + return queryset.filter(level__lte=value) + + +class StockLocationTree(TreeMixin, ListAPI): """API endpoint for accessing a list of StockLocation objects, ready for rendering as a tree.""" + model_class = StockLocation queryset = StockLocation.objects.all() serializer_class = StockSerializers.LocationTreeSerializer - - filter_backends = ORDER_FILTER - - ordering_fields = ['level', 'name', 'sublocations'] - - # Order by tree level (top levels first) and then name - ordering = ['level', 'name'] - - ordering_field_aliases = {'level': ['level', 'name'], 'name': ['name', 'level']} + filterset_class = LocationTreeFilter def get_queryset(self, *args, **kwargs): """Return annotated queryset for the StockLocationTree endpoint.""" diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 4943dd6dfe..90b1770e62 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -1160,7 +1160,18 @@ class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer): """Metaclass options.""" model = StockLocation - fields = ['pk', 'name', 'parent', 'icon', 'structural', 'sublocations'] + fields = [ + 'pk', + 'name', + 'description', + 'pathstring', + 'parent', + 'tree_id', + 'level', + 'icon', + 'structural', + 'sublocations', + ] sublocations = serializers.IntegerField(label=_('Sublocations'), read_only=True)