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

Directly annotate parameters against different model serializers

This commit is contained in:
Oliver Walters
2025-11-25 01:31:51 +00:00
parent 6369cc89cb
commit 5b4a8d50e6
3 changed files with 61 additions and 66 deletions

View File

@@ -168,9 +168,28 @@ class ManufacturerOutputOptions(OutputConfiguration):
] ]
class ManufacturerPartMixin(SerializerContextMixin):
"""Mixin class for ManufacturerPart API endpoints."""
queryset = ManufacturerPart.objects.all()
serializer_class = ManufacturerPartSerializer
def get_queryset(self, *args, **kwargs):
"""Return annotated queryset for the ManufacturerPart list endpoint."""
queryset = super().get_queryset(*args, **kwargs)
queryset = queryset.prefetch_related(
'part', 'manufacturer', 'supplier_parts', 'tags'
)
queryset = ManufacturerPart.annotate_parameters(queryset)
return queryset
class ManufacturerPartList( class ManufacturerPartList(
ManufacturerPartMixin,
SerializerContextMixin, SerializerContextMixin,
DataExportViewMixin,
OutputOptionsMixin, OutputOptionsMixin,
ListCreateDestroyAPIView, ListCreateDestroyAPIView,
): ):
@@ -180,13 +199,10 @@ class ManufacturerPartList(
- POST: Create a new ManufacturerPart object - POST: Create a new ManufacturerPart object
""" """
queryset = ManufacturerPart.objects.all().prefetch_related(
'part', 'manufacturer', 'supplier_parts', 'tags'
)
serializer_class = ManufacturerPartSerializer
filterset_class = ManufacturerPartFilter filterset_class = ManufacturerPartFilter
output_options = ManufacturerOutputOptions
filter_backends = SEARCH_ORDER_FILTER filter_backends = SEARCH_ORDER_FILTER
output_options = ManufacturerOutputOptions
search_fields = [ search_fields = [
'manufacturer__name', 'manufacturer__name',
'description', 'description',
@@ -199,7 +215,9 @@ class ManufacturerPartList(
] ]
class ManufacturerPartDetail(RetrieveUpdateDestroyAPI): class ManufacturerPartDetail(
ManufacturerPartMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI
):
"""API endpoint for detail view of ManufacturerPart object. """API endpoint for detail view of ManufacturerPart object.
- GET: Retrieve detail view - GET: Retrieve detail view
@@ -207,9 +225,6 @@ class ManufacturerPartDetail(RetrieveUpdateDestroyAPI):
- DELETE: Delete object - DELETE: Delete object
""" """
queryset = ManufacturerPart.objects.all()
serializer_class = ManufacturerPartSerializer
class SupplierPartFilter(FilterSet): class SupplierPartFilter(FilterSet):
"""API filters for the SupplierPartList endpoint.""" """API filters for the SupplierPartList endpoint."""
@@ -310,7 +325,7 @@ class SupplierPartMixin:
serializer_class = SupplierPartSerializer serializer_class = SupplierPartSerializer
def get_queryset(self, *args, **kwargs): def get_queryset(self, *args, **kwargs):
"""Return annotated queryest object for the SupplierPart list.""" """Return annotated queryset object for the SupplierPart list."""
queryset = super().get_queryset(*args, **kwargs) queryset = super().get_queryset(*args, **kwargs)
queryset = SupplierPartSerializer.annotate_queryset(queryset) queryset = SupplierPartSerializer.annotate_queryset(queryset)

View File

@@ -11,6 +11,7 @@ from rest_framework import serializers
from sql_util.utils import SubqueryCount from sql_util.utils import SubqueryCount
from taggit.serializers import TagListSerializerField from taggit.serializers import TagListSerializerField
import common.serializers
import company.filters import company.filters
import part.filters import part.filters
import part.serializers as part_serializers import part.serializers as part_serializers
@@ -112,6 +113,7 @@ class AddressBriefSerializer(InvenTreeModelSerializer):
@register_importer() @register_importer()
class CompanySerializer( class CompanySerializer(
FilterableSerializerMixin,
DataImportExportSerializerMixin, DataImportExportSerializerMixin,
NotesFieldMixin, NotesFieldMixin,
RemoteImageMixin, RemoteImageMixin,
@@ -151,6 +153,7 @@ class CompanySerializer(
'address_count', 'address_count',
'primary_address', 'primary_address',
'tax_id', 'tax_id',
'parameters',
] ]
@staticmethod @staticmethod
@@ -173,6 +176,8 @@ class CompanySerializer(
) )
) )
queryset = Company.annotate_parameters(queryset)
return queryset return queryset
address = serializers.SerializerMethodField( address = serializers.SerializerMethodField(
@@ -211,6 +216,12 @@ class CompanySerializer(
help_text=_('Default currency used for this supplier'), required=True help_text=_('Default currency used for this supplier'), required=True
) )
parameters = enable_filter(
common.serializers.ParameterSerializer(many=True, read_only=True),
False,
filter_name='parameters',
)
def save(self): def save(self):
"""Save the Company instance.""" """Save the Company instance."""
super().save() super().save()
@@ -274,10 +285,17 @@ class ManufacturerPartSerializer(
'barcode_hash', 'barcode_hash',
'notes', 'notes',
'tags', 'tags',
'parameters',
] ]
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
parameters = enable_filter(
common.serializers.ParameterSerializer(many=True, read_only=True),
False,
filter_name='parameters',
)
part_detail = enable_filter( part_detail = enable_filter(
part_serializers.PartBriefSerializer( part_serializers.PartBriefSerializer(
source='part', many=False, read_only=True, allow_null=True source='part', many=False, read_only=True, allow_null=True
@@ -387,6 +405,7 @@ class SupplierPartSerializer(
'part_detail', 'part_detail',
'tags', 'tags',
'price_breaks', 'price_breaks',
'parameters',
] ]
read_only_fields = [ read_only_fields = [
'availability_updated', 'availability_updated',
@@ -459,6 +478,12 @@ class SupplierPartSerializer(
filter_name='price_breaks', filter_name='price_breaks',
) )
parameters = enable_filter(
common.serializers.ParameterSerializer(many=True, read_only=True),
False,
filter_name='parameters',
)
part_detail = part_serializers.PartBriefSerializer( part_detail = part_serializers.PartBriefSerializer(
label=_('Part'), source='part', many=False, read_only=True, allow_null=True label=_('Part'), source='part', many=False, read_only=True, allow_null=True
) )
@@ -515,6 +540,8 @@ class SupplierPartSerializer(
on_order=company.filters.annotate_on_order_quantity() on_order=company.filters.annotate_on_order_quantity()
) )
queryset = SupplierPart.annotate_parameters(queryset)
return queryset return queryset
def update(self, supplier_part, data): def update(self, supplier_part, data):

View File

@@ -22,6 +22,7 @@ from sql_util.utils import SubqueryCount
from taggit.serializers import TagListSerializerField from taggit.serializers import TagListSerializerField
import common.currency import common.currency
import common.serializers
import company.models import company.models
import InvenTree.helpers import InvenTree.helpers
import InvenTree.serializers import InvenTree.serializers
@@ -394,60 +395,6 @@ class PartBriefSerializer(
) )
@register_importer()
class PartParameterSerializer(
InvenTree.serializers.FilterableSerializerMixin,
DataImportExportSerializerMixin,
InvenTree.serializers.InvenTreeModelSerializer,
):
"""JSON serializers for the PartParameter model."""
class Meta:
"""Metaclass defining serializer fields."""
model = PartParameter
fields = [
'pk',
'part',
'part_detail',
'template',
'template_detail',
'data',
'data_numeric',
'note',
'updated',
'updated_by',
'updated_by_detail',
]
read_only_fields = ['updated', 'updated_by']
def save(self):
"""Save the PartParameter instance."""
instance = super().save()
if request := self.context.get('request', None):
# If the request is provided, update the 'updated_by' field
instance.updated_by = request.user
instance.save()
return instance
part_detail = enable_filter(
PartBriefSerializer(source='part', many=False, read_only=True, allow_null=True)
)
template_detail = enable_filter(
PartParameterTemplateSerializer(
source='template', many=False, read_only=True, allow_null=True
),
True,
)
updated_by_detail = UserSerializer(
source='updated_by', many=False, read_only=True, allow_null=True
)
class DuplicatePartSerializer(serializers.Serializer): class DuplicatePartSerializer(serializers.Serializer):
"""Serializer for specifying options when duplicating a Part. """Serializer for specifying options when duplicating a Part.
@@ -771,6 +718,8 @@ class PartSerializer(
""" """
queryset = queryset.prefetch_related('category', 'default_location') queryset = queryset.prefetch_related('category', 'default_location')
queryset = Part.annotate_parameters(queryset)
# Annotate with the total number of revisions # Annotate with the total number of revisions
queryset = queryset.annotate(revision_count=SubqueryCount('revisions')) queryset = queryset.annotate(revision_count=SubqueryCount('revisions'))
@@ -1010,7 +959,11 @@ class PartSerializer(
) )
parameters = enable_filter( parameters = enable_filter(
PartParameterSerializer(many=True, read_only=True, allow_null=True) common.serializers.ParameterSerializer(
many=True, read_only=True, allow_null=True
),
False,
filter_name='parameters',
) )
price_breaks = enable_filter( price_breaks = enable_filter(