mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Update PartParameterTemplate API (#6538)
* Update PartParameterTemplate API - Expose number of "parts" using a particular template - Improve filtering visibility - Update PUI table * Update API version
This commit is contained in:
parent
0bfbd45cec
commit
defa03b83a
@ -1,11 +1,14 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 174
|
INVENTREE_API_VERSION = 175
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
|
||||||
|
v175 - 2024-02-21 : https://github.com/inventree/InvenTree/pull/6538
|
||||||
|
- Adds "parts" count to PartParameterTemplate serializer
|
||||||
|
|
||||||
v174 - 2024-02-21 : https://github.com/inventree/InvenTree/pull/6536
|
v174 - 2024-02-21 : https://github.com/inventree/InvenTree/pull/6536
|
||||||
- Expose PartCategory filters to the API documentation
|
- Expose PartCategory filters to the API documentation
|
||||||
- Expose StockLocation filters to the API documentation
|
- Expose StockLocation filters to the API documentation
|
||||||
|
@ -1494,7 +1494,7 @@ class PartParameterTemplateFilter(rest_filters.FilterSet):
|
|||||||
model = PartParameterTemplate
|
model = PartParameterTemplate
|
||||||
|
|
||||||
# Simple filter fields
|
# Simple filter fields
|
||||||
fields = ['units', 'checkbox']
|
fields = ['name', 'units', 'checkbox']
|
||||||
|
|
||||||
has_choices = rest_filters.BooleanFilter(
|
has_choices = rest_filters.BooleanFilter(
|
||||||
method='filter_has_choices', label='Has Choice'
|
method='filter_has_choices', label='Has Choice'
|
||||||
@ -1516,65 +1516,68 @@ class PartParameterTemplateFilter(rest_filters.FilterSet):
|
|||||||
|
|
||||||
return queryset.filter(Q(units=None) | Q(units='')).distinct()
|
return queryset.filter(Q(units=None) | Q(units='')).distinct()
|
||||||
|
|
||||||
|
part = rest_filters.ModelChoiceFilter(
|
||||||
|
queryset=Part.objects.all(), method='filter_part', label=_('Part')
|
||||||
|
)
|
||||||
|
|
||||||
class PartParameterTemplateList(ListCreateAPI):
|
def filter_part(self, queryset, name, part):
|
||||||
|
"""Filter queryset to include only PartParameterTemplates which are referenced by a part."""
|
||||||
|
parameters = PartParameter.objects.filter(part=part)
|
||||||
|
template_ids = parameters.values_list('template').distinct()
|
||||||
|
return queryset.filter(pk__in=[el[0] for el in template_ids])
|
||||||
|
|
||||||
|
# Filter against a "PartCategory" - return only parameter templates which are referenced by parts in this category
|
||||||
|
category = rest_filters.ModelChoiceFilter(
|
||||||
|
queryset=PartCategory.objects.all(),
|
||||||
|
method='filter_category',
|
||||||
|
label=_('Category'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def filter_category(self, queryset, name, category):
|
||||||
|
"""Filter queryset to include only PartParameterTemplates which are referenced by parts in this category."""
|
||||||
|
cats = category.get_descendants(include_self=True)
|
||||||
|
parameters = PartParameter.objects.filter(part__category__in=cats)
|
||||||
|
template_ids = parameters.values_list('template').distinct()
|
||||||
|
return queryset.filter(pk__in=[el[0] for el in template_ids])
|
||||||
|
|
||||||
|
|
||||||
|
class PartParameterTemplateMixin:
|
||||||
|
"""Mixin class for PartParameterTemplate API endpoints."""
|
||||||
|
|
||||||
|
queryset = PartParameterTemplate.objects.all()
|
||||||
|
serializer_class = part_serializers.PartParameterTemplateSerializer
|
||||||
|
|
||||||
|
def get_queryset(self, *args, **kwargs):
|
||||||
|
"""Return an annotated queryset for the PartParameterTemplateDetail endpoint."""
|
||||||
|
queryset = super().get_queryset(*args, **kwargs)
|
||||||
|
|
||||||
|
queryset = part_serializers.PartParameterTemplateSerializer.annotate_queryset(
|
||||||
|
queryset
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class PartParameterTemplateList(PartParameterTemplateMixin, ListCreateAPI):
|
||||||
"""API endpoint for accessing a list of PartParameterTemplate objects.
|
"""API endpoint for accessing a list of PartParameterTemplate objects.
|
||||||
|
|
||||||
- GET: Return list of PartParameterTemplate objects
|
- GET: Return list of PartParameterTemplate objects
|
||||||
- POST: Create a new PartParameterTemplate object
|
- POST: Create a new PartParameterTemplate object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = PartParameterTemplate.objects.all()
|
|
||||||
serializer_class = part_serializers.PartParameterTemplateSerializer
|
|
||||||
filterset_class = PartParameterTemplateFilter
|
filterset_class = PartParameterTemplateFilter
|
||||||
|
|
||||||
filter_backends = SEARCH_ORDER_FILTER
|
filter_backends = SEARCH_ORDER_FILTER
|
||||||
|
|
||||||
filterset_fields = ['name']
|
|
||||||
|
|
||||||
search_fields = ['name', 'description']
|
search_fields = ['name', 'description']
|
||||||
|
|
||||||
ordering_fields = ['name', 'units', 'checkbox']
|
ordering_fields = ['name', 'units', 'checkbox', 'parts']
|
||||||
|
|
||||||
def filter_queryset(self, queryset):
|
|
||||||
"""Custom filtering for the PartParameterTemplate API."""
|
|
||||||
queryset = super().filter_queryset(queryset)
|
|
||||||
|
|
||||||
params = self.request.query_params
|
|
||||||
|
|
||||||
# Filtering against a "Part" - return only parameter templates which are referenced by a part
|
|
||||||
part = params.get('part', None)
|
|
||||||
|
|
||||||
if part is not None:
|
|
||||||
try:
|
|
||||||
part = Part.objects.get(pk=part)
|
|
||||||
parameters = PartParameter.objects.filter(part=part)
|
|
||||||
template_ids = parameters.values_list('template').distinct()
|
|
||||||
queryset = queryset.filter(pk__in=[el[0] for el in template_ids])
|
|
||||||
except (ValueError, Part.DoesNotExist):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Filtering against a "PartCategory" - return only parameter templates which are referenced by parts in this category
|
|
||||||
category = params.get('category', None)
|
|
||||||
|
|
||||||
if category is not None:
|
|
||||||
try:
|
|
||||||
category = PartCategory.objects.get(pk=category)
|
|
||||||
cats = category.get_descendants(include_self=True)
|
|
||||||
parameters = PartParameter.objects.filter(part__category__in=cats)
|
|
||||||
template_ids = parameters.values_list('template').distinct()
|
|
||||||
queryset = queryset.filter(pk__in=[el[0] for el in template_ids])
|
|
||||||
except (ValueError, PartCategory.DoesNotExist):
|
|
||||||
pass
|
|
||||||
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
|
|
||||||
class PartParameterTemplateDetail(RetrieveUpdateDestroyAPI):
|
class PartParameterTemplateDetail(PartParameterTemplateMixin, RetrieveUpdateDestroyAPI):
|
||||||
"""API endpoint for accessing the detail view for a PartParameterTemplate object."""
|
"""API endpoint for accessing the detail view for a PartParameterTemplate object."""
|
||||||
|
|
||||||
queryset = PartParameterTemplate.objects.all()
|
pass
|
||||||
serializer_class = part_serializers.PartParameterTemplateSerializer
|
|
||||||
|
|
||||||
|
|
||||||
class PartParameterAPIMixin:
|
class PartParameterAPIMixin:
|
||||||
|
@ -245,7 +245,18 @@ class PartParameterTemplateSerializer(InvenTree.serializers.InvenTreeModelSerial
|
|||||||
"""Metaclass defining serializer fields."""
|
"""Metaclass defining serializer fields."""
|
||||||
|
|
||||||
model = PartParameterTemplate
|
model = PartParameterTemplate
|
||||||
fields = ['pk', 'name', 'units', 'description', 'checkbox', 'choices']
|
fields = ['pk', 'name', 'units', 'description', 'parts', 'checkbox', 'choices']
|
||||||
|
|
||||||
|
parts = serializers.IntegerField(
|
||||||
|
read_only=True,
|
||||||
|
label=_('Parts'),
|
||||||
|
help_text=_('Number of parts using this template'),
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def annotate_queryset(queryset):
|
||||||
|
"""Annotate the queryset with the number of parts which use each parameter template."""
|
||||||
|
return queryset.annotate(parts=SubqueryCount('instances'))
|
||||||
|
|
||||||
|
|
||||||
class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||||
|
@ -51,6 +51,11 @@ export default function PartParameterTemplateTable() {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
switchable: false
|
switchable: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessor: 'parts',
|
||||||
|
sortable: true,
|
||||||
|
switchable: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessor: 'units',
|
accessor: 'units',
|
||||||
sortable: true
|
sortable: true
|
||||||
|
Loading…
Reference in New Issue
Block a user