2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-16 17:28:11 +00:00

Add generic API mixin for filtering and ordering by parameter

This commit is contained in:
Oliver Walters
2025-11-25 05:33:41 +00:00
parent a617cece72
commit 5533a374f2
4 changed files with 46 additions and 24 deletions

View File

@@ -600,6 +600,32 @@ class BulkUpdateMixin(BulkOperationMixin):
return Response({'success': f'Updated {n} items'}, status=200) return Response({'success': f'Updated {n} items'}, status=200)
class ParameterListMixin:
"""Mixin class which supports filtering against parametric fields."""
parameter_model_class = None
def filter_queryset(self, queryset):
"""Perform filtering against parametric fields."""
import common.filters
queryset = super().filter_queryset(queryset)
# Filter by parametric data
queryset = common.filters.filter_parametric_data(
queryset, self.request.query_params
)
# Apply ordering based on query parameter
queryset = common.filters.order_by_parameter(
queryset,
self.parameter_model_class,
self.request.query_params.get('ordering', None),
)
return queryset
class BulkDeleteMixin(BulkOperationMixin): class BulkDeleteMixin(BulkOperationMixin):
"""Mixin class for enabling 'bulk delete' operations for various models. """Mixin class for enabling 'bulk delete' operations for various models.

View File

@@ -9,7 +9,7 @@ from django_filters.rest_framework.filterset import FilterSet
import part.models import part.models
from data_exporter.mixins import DataExportViewMixin from data_exporter.mixins import DataExportViewMixin
from InvenTree.api import ListCreateDestroyAPIView, MetadataView from InvenTree.api import ListCreateDestroyAPIView, MetadataView, ParameterListMixin
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS
from InvenTree.mixins import ( from InvenTree.mixins import (
@@ -51,7 +51,7 @@ class CompanyMixin(OutputOptionsMixin):
return queryset return queryset
class CompanyList(CompanyMixin, DataExportViewMixin, ListCreateAPI): class CompanyList(CompanyMixin, ParameterListMixin, DataExportViewMixin, ListCreateAPI):
"""API endpoint for accessing a list of Company objects. """API endpoint for accessing a list of Company objects.
Provides two methods: Provides two methods:
@@ -60,6 +60,7 @@ class CompanyList(CompanyMixin, DataExportViewMixin, ListCreateAPI):
- POST: Create a new Company object - POST: Create a new Company object
""" """
parameter_model_class = Company
filter_backends = SEARCH_ORDER_FILTER filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [ filterset_fields = [
@@ -191,6 +192,7 @@ class ManufacturerPartList(
ManufacturerPartMixin, ManufacturerPartMixin,
SerializerContextMixin, SerializerContextMixin,
OutputOptionsMixin, OutputOptionsMixin,
ParameterListMixin,
ListCreateDestroyAPIView, ListCreateDestroyAPIView,
): ):
"""API endpoint for list view of ManufacturerPart object. """API endpoint for list view of ManufacturerPart object.
@@ -199,6 +201,7 @@ class ManufacturerPartList(
- POST: Create a new ManufacturerPart object - POST: Create a new ManufacturerPart object
""" """
parameter_model_class = ManufacturerPart
filterset_class = ManufacturerPartFilter filterset_class = ManufacturerPartFilter
filter_backends = SEARCH_ORDER_FILTER filter_backends = SEARCH_ORDER_FILTER
output_options = ManufacturerOutputOptions output_options = ManufacturerOutputOptions
@@ -337,7 +340,11 @@ class SupplierPartMixin:
class SupplierPartList( class SupplierPartList(
DataExportViewMixin, SupplierPartMixin, OutputOptionsMixin, ListCreateDestroyAPIView DataExportViewMixin,
SupplierPartMixin,
ParameterListMixin,
OutputOptionsMixin,
ListCreateDestroyAPIView,
): ):
"""API endpoint for list view of SupplierPart object. """API endpoint for list view of SupplierPart object.
@@ -345,8 +352,8 @@ class SupplierPartList(
- POST: Create a new SupplierPart object - POST: Create a new SupplierPart object
""" """
parameter_model_class = SupplierPart
filterset_class = SupplierPartFilter filterset_class = SupplierPartFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS filter_backends = SEARCH_ORDER_FILTER_ALIAS
output_options = SupplierPartOutputOptions output_options = SupplierPartOutputOptions

View File

@@ -19,6 +19,7 @@ from InvenTree.api import (
BulkUpdateMixin, BulkUpdateMixin,
ListCreateDestroyAPIView, ListCreateDestroyAPIView,
MetadataView, MetadataView,
ParameterListMixin,
) )
from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration
from InvenTree.filters import ( from InvenTree.filters import (
@@ -1066,32 +1067,20 @@ class PartOutputOptions(OutputConfiguration):
class PartList( class PartList(
PartMixin, BulkUpdateMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateAPI PartMixin,
BulkUpdateMixin,
ParameterListMixin,
DataExportViewMixin,
OutputOptionsMixin,
ListCreateAPI,
): ):
"""API endpoint for accessing a list of Part objects, or creating a new Part instance.""" """API endpoint for accessing a list of Part objects, or creating a new Part instance."""
parameter_model_class = Part
output_options = PartOutputOptions output_options = PartOutputOptions
filterset_class = PartFilter filterset_class = PartFilter
is_create = True is_create = True
def filter_queryset(self, queryset):
"""Perform custom filtering of the queryset."""
import common.filters
queryset = super().filter_queryset(queryset)
# Filter by parametric data
queryset = common.filters.filter_parametric_data(
queryset, self.request.query_params
)
# Apply ordering based on query parameter
queryset = common.filters.order_by_parameter(
queryset, Part, self.request.query_params.get('ordering', None)
)
return queryset
filter_backends = SEARCH_ORDER_FILTER_ALIAS filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_fields = [ ordering_fields = [

View File

@@ -33,7 +33,7 @@ export default function SegmentedIconControl({
data={data.map((item) => ({ data={data.map((item) => ({
value: item.value, value: item.value,
label: ( label: (
<Tooltip label={item.label}> <Tooltip label={item.label} position='top-end'>
<ActionIcon <ActionIcon
variant='transparent' variant='transparent'
color={color} color={color}