mirror of
https://github.com/inventree/InvenTree.git
synced 2026-08-10 15:36:17 +00:00
Fix for N+1 issues in stock item serializing (#12534)
This commit is contained in:
@@ -143,8 +143,16 @@ class StockItemSerialize(StockItemContextMixin, CreateAPI):
|
|||||||
|
|
||||||
queryset = StockSerializers.StockItemSerializer.annotate_queryset(items)
|
queryset = StockSerializers.StockItemSerializer.annotate_queryset(items)
|
||||||
|
|
||||||
|
# Apply any additional prefetching required by optional fields which end up
|
||||||
|
# included in this response (e.g. 'tags', 'tests') - mirrors what
|
||||||
|
# OutputOptionsMixin.get_queryset() does for a normal list/retrieve request,
|
||||||
|
# which this manually-constructed response bypasses
|
||||||
|
context = self.get_serializer_context()
|
||||||
|
probe_serializer = StockSerializers.StockItemSerializer(context=context)
|
||||||
|
queryset = probe_serializer.prefetch_queryset(queryset)
|
||||||
|
|
||||||
response = StockSerializers.StockItemSerializer(
|
response = StockSerializers.StockItemSerializer(
|
||||||
queryset, many=True, context=self.get_serializer_context()
|
queryset, many=True, context=context
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(response.data, status=status.HTTP_201_CREATED)
|
return Response(response.data, status=status.HTTP_201_CREATED)
|
||||||
|
|||||||
@@ -2489,7 +2489,18 @@ class StockItem(
|
|||||||
# Create a new tracking entry for each item
|
# Create a new tracking entry for each item
|
||||||
history_items = []
|
history_items = []
|
||||||
|
|
||||||
|
# Every new item shares this exact part - avoid a redundant per-item
|
||||||
|
# part_id -> Part lookup (bulk_create_and_fetch() does not preserve the
|
||||||
|
# cached FK) by seeding each item's cache with the instance we already have
|
||||||
|
part = self.part
|
||||||
|
|
||||||
|
# Check (once) whether there are any test results to copy across, rather
|
||||||
|
# than re-querying an identical (and usually empty) result set per item
|
||||||
|
has_test_results = self.test_results.exists()
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
|
item.part = part
|
||||||
|
|
||||||
# Construct tracking entries for the new StockItem
|
# Construct tracking entries for the new StockItem
|
||||||
if entry := item.add_tracking_entry(
|
if entry := item.add_tracking_entry(
|
||||||
StockHistoryCode.SPLIT_FROM_PARENT,
|
StockHistoryCode.SPLIT_FROM_PARENT,
|
||||||
@@ -2512,7 +2523,8 @@ class StockItem(
|
|||||||
history_items.append(entry)
|
history_items.append(entry)
|
||||||
|
|
||||||
# Copy any test results from this item to the new one
|
# Copy any test results from this item to the new one
|
||||||
item.copyTestResultsFrom(self)
|
if has_test_results:
|
||||||
|
item.copyTestResultsFrom(self)
|
||||||
|
|
||||||
StockItemTracking.objects.bulk_create(history_items, batch_size=250)
|
StockItemTracking.objects.bulk_create(history_items, batch_size=250)
|
||||||
|
|
||||||
|
|||||||
@@ -1702,9 +1702,8 @@ class StockItemTest(StockAPITestCase):
|
|||||||
with self.settings(
|
with self.settings(
|
||||||
PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True
|
PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True
|
||||||
):
|
):
|
||||||
# TODO: 2026-07-12 : Refactor this API call
|
|
||||||
response = self.post(
|
response = self.post(
|
||||||
url, data, max_query_count=1300, benchmark=True, format='json'
|
url, data, max_query_count=150, benchmark=True, format='json'
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|||||||
Reference in New Issue
Block a user