mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-17 01:38:19 +00:00
[API] API refactoring (#11023)
* API refactoring - Specify prefetch_fields for optional child serializers - Ref: https://github.com/inventree/InvenTree/pull/11012/ * Fixes for unit tests
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 432
|
||||
INVENTREE_API_VERSION = 433
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v433 -> 2025-12-16 : https://github.com/inventree/InvenTree/pull/11023
|
||||
- "substitutes" field on the BomItem API endpoint is now excluded by default
|
||||
- Add "?substitutes=true" query parameter to include substitute parts in BomItem API endpoint(s)
|
||||
|
||||
v432 -> 2025-12-15 : https://github.com/inventree/InvenTree/pull/11012
|
||||
- The "part_detail" field on the SupplierPart API endpoint is now optional
|
||||
- The "supplier_detail" field on the SupplierPart API endpoint is now optional
|
||||
|
||||
@@ -1435,6 +1435,7 @@ class BuildLineSerializer(
|
||||
can_build=False,
|
||||
),
|
||||
False,
|
||||
prefetch_fields=['bom_item'],
|
||||
)
|
||||
|
||||
assembly_detail = enable_filter(
|
||||
|
||||
@@ -893,9 +893,7 @@ class ParameterFilter(FilterSet):
|
||||
class ParameterMixin:
|
||||
"""Mixin class for Parameter views."""
|
||||
|
||||
queryset = common.models.Parameter.objects.all().prefetch_related(
|
||||
'model_type', 'updated_by', 'template', 'template__model_type'
|
||||
)
|
||||
queryset = common.models.Parameter.objects.all().prefetch_related('model_type')
|
||||
serializer_class = common.serializers.ParameterSerializer
|
||||
permission_classes = [IsAuthenticatedOrReadScope]
|
||||
|
||||
|
||||
@@ -808,11 +808,15 @@ class ParameterSerializer(
|
||||
)
|
||||
|
||||
updated_by_detail = enable_filter(
|
||||
UserSerializer(source='updated_by', read_only=True, many=False), True
|
||||
UserSerializer(source='updated_by', read_only=True, many=False),
|
||||
True,
|
||||
prefetch_fields=['updated_by'],
|
||||
)
|
||||
|
||||
template_detail = enable_filter(
|
||||
ParameterTemplateSerializer(source='template', read_only=True, many=False), True
|
||||
ParameterTemplateSerializer(source='template', read_only=True, many=False),
|
||||
True,
|
||||
prefetch_fields=['template', 'template__model_type'],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -430,13 +430,6 @@ class SupplierPriceBreakMixin:
|
||||
queryset = SupplierPriceBreak.objects.all()
|
||||
serializer_class = SupplierPriceBreakSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return annotated queryset for the SupplierPriceBreak list endpoint."""
|
||||
queryset = super().get_queryset()
|
||||
queryset = SupplierPriceBreakSerializer.annotate_queryset(queryset)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class SupplierPriceBreakOutputOptions(OutputConfiguration):
|
||||
"""Available output options for the SupplierPriceBreak endpoints."""
|
||||
|
||||
@@ -572,7 +572,9 @@ class SupplierPriceBreakSerializer(
|
||||
supplier_detail = enable_filter(
|
||||
CompanyBriefSerializer(
|
||||
source='part.supplier', many=False, read_only=True, allow_null=True
|
||||
)
|
||||
),
|
||||
False,
|
||||
prefetch_fields=['part__supplier'],
|
||||
)
|
||||
|
||||
part_detail = enable_filter(
|
||||
@@ -580,4 +582,5 @@ class SupplierPriceBreakSerializer(
|
||||
source='part', brief=True, many=False, read_only=True, allow_null=True
|
||||
),
|
||||
False,
|
||||
prefetch_fields=['part', 'part__part', 'part__part__pricing_data'],
|
||||
)
|
||||
|
||||
@@ -570,7 +570,7 @@ class PartPricingDetail(RetrieveUpdateAPI):
|
||||
"""API endpoint for viewing part pricing data."""
|
||||
|
||||
serializer_class = part_serializers.PartPricingSerializer
|
||||
queryset = Part.objects.all()
|
||||
queryset = Part.objects.all().select_related('pricing_data')
|
||||
|
||||
def get_object(self):
|
||||
"""Return the PartPricing object associated with the linked Part."""
|
||||
@@ -1361,6 +1361,8 @@ class BomOutputOptions(OutputConfiguration):
|
||||
InvenTreeOutputOption('can_build', default=True),
|
||||
InvenTreeOutputOption('part_detail'),
|
||||
InvenTreeOutputOption('sub_part_detail'),
|
||||
InvenTreeOutputOption('substitutes'),
|
||||
InvenTreeOutputOption('pricing'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1563,7 +1563,15 @@ class BomItemSerializer(
|
||||
)
|
||||
|
||||
substitutes = enable_filter(
|
||||
BomItemSubstituteSerializer(many=True, read_only=True, allow_null=True), True
|
||||
BomItemSubstituteSerializer(many=True, read_only=True, allow_null=True),
|
||||
False,
|
||||
filter_name='substitutes',
|
||||
prefetch_fields=[
|
||||
'substitutes',
|
||||
'substitutes__part',
|
||||
'substitutes__part__stock_items',
|
||||
'substitutes__part__pricing_data',
|
||||
],
|
||||
)
|
||||
|
||||
part_detail = enable_filter(
|
||||
@@ -1684,9 +1692,7 @@ class BomItemSerializer(
|
||||
'sub_part__stock_items',
|
||||
'sub_part__stock_items__allocations',
|
||||
'sub_part__stock_items__sales_order_allocations',
|
||||
'substitutes',
|
||||
'substitutes__part__stock_items',
|
||||
).select_related('part__pricing_data', 'sub_part__pricing_data')
|
||||
)
|
||||
|
||||
# Annotate with the 'total pricing' information based on unit pricing and quantity
|
||||
queryset = queryset.annotate(
|
||||
@@ -1751,6 +1757,7 @@ class CategoryParameterTemplateSerializer(
|
||||
source='template', many=False, read_only=True
|
||||
),
|
||||
True,
|
||||
prefetch_fields=['template'],
|
||||
)
|
||||
|
||||
category_detail = enable_filter(
|
||||
@@ -1758,6 +1765,7 @@ class CategoryParameterTemplateSerializer(
|
||||
source='category', many=False, read_only=True, allow_null=True
|
||||
),
|
||||
True,
|
||||
prefetch_fields=['category'],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -2708,7 +2708,7 @@ class BomItemTest(InvenTreeAPITestCase):
|
||||
"""Get the detail view for a single BomItem object."""
|
||||
url = reverse('api-bom-item-detail', kwargs={'pk': 3})
|
||||
|
||||
response = self.get(url, expected_code=200)
|
||||
response = self.get(url, {'substitutes': True}, expected_code=200)
|
||||
|
||||
expected_values = [
|
||||
'allow_variants',
|
||||
@@ -2882,6 +2882,7 @@ class BomItemTest(InvenTreeAPITestCase):
|
||||
# The BomItem detail endpoint should now also reflect the substitute data
|
||||
data = self.get(
|
||||
reverse('api-bom-item-detail', kwargs={'pk': bom_item.pk}),
|
||||
data={'substitutes': True},
|
||||
expected_code=200,
|
||||
).data
|
||||
|
||||
|
||||
@@ -223,7 +223,8 @@ class StockItemTestResultSerializer(
|
||||
read_only_fields = ['pk', 'user', 'date']
|
||||
|
||||
user_detail = enable_filter(
|
||||
UserSerializer(source='user', read_only=True, allow_null=True)
|
||||
UserSerializer(source='user', read_only=True, allow_null=True),
|
||||
prefetch_fields=['user'],
|
||||
)
|
||||
|
||||
template = serializers.PrimaryKeyRelatedField(
|
||||
@@ -238,7 +239,8 @@ class StockItemTestResultSerializer(
|
||||
template_detail = enable_filter(
|
||||
part_serializers.PartTestTemplateSerializer(
|
||||
source='template', read_only=True, allow_null=True
|
||||
)
|
||||
),
|
||||
prefetch_fields=['template'],
|
||||
)
|
||||
|
||||
attachment = InvenTree.serializers.InvenTreeAttachmentSerializerField(
|
||||
@@ -1244,11 +1246,13 @@ class StockTrackingSerializer(
|
||||
label = serializers.CharField(read_only=True)
|
||||
|
||||
item_detail = enable_filter(
|
||||
StockItemSerializer(source='item', many=False, read_only=True, allow_null=True)
|
||||
StockItemSerializer(source='item', many=False, read_only=True, allow_null=True),
|
||||
prefetch_fields=['item'],
|
||||
)
|
||||
|
||||
user_detail = enable_filter(
|
||||
UserSerializer(source='user', many=False, read_only=True, allow_null=True)
|
||||
UserSerializer(source='user', many=False, read_only=True, allow_null=True),
|
||||
prefetch_fields=['user'],
|
||||
)
|
||||
|
||||
deltas = serializers.JSONField(read_only=True)
|
||||
|
||||
@@ -291,13 +291,6 @@ class GroupMixin(SerializerContextMixin):
|
||||
serializer_class = GroupSerializer
|
||||
permission_classes = [InvenTree.permissions.IsStaffOrReadOnlyScope]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return queryset for this endpoint.
|
||||
|
||||
Note that the queryset is filtered by the permissions of the current user.
|
||||
"""
|
||||
return super().get_queryset().prefetch_related('rule_sets', 'user_set')
|
||||
|
||||
|
||||
class GroupOutputOptions(OutputConfiguration):
|
||||
"""Holds all available output options for Group views."""
|
||||
|
||||
@@ -268,11 +268,13 @@ class GroupSerializer(FilterableSerializerMixin, InvenTreeModelSerializer):
|
||||
source='rule_sets', many=True, read_only=True, allow_null=True
|
||||
),
|
||||
filter_name='role_detail',
|
||||
prefetch_fields=['rule_sets'],
|
||||
)
|
||||
|
||||
users = enable_filter(
|
||||
UserSerializer(source='user_set', many=True, read_only=True, allow_null=True),
|
||||
filter_name='user_detail',
|
||||
prefetch_fields=['user_set'],
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user