2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-03 05:48:47 +00:00

Merge pull request #904 from SchrodingersGat/query-speeds

Significant query speed improvements to stock list API
This commit is contained in:
Oliver 2020-08-15 21:56:55 +10:00 committed by GitHub
commit 318c16f321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 12 deletions

View File

@ -99,6 +99,10 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
if manufacturer_detail is not True: if manufacturer_detail is not True:
self.fields.pop('manufacturer_detail') self.fields.pop('manufacturer_detail')
supplier = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_supplier=True))
manufacturer = serializers.PrimaryKeyRelatedField(queryset=Company.objects.filter(is_manufacturer=True))
class Meta: class Meta:
model = SupplierPart model = SupplierPart
fields = [ fields = [

View File

@ -604,6 +604,19 @@ class BomList(generics.ListCreateAPIView):
serializer_class = part_serializers.BomItemSerializer serializer_class = part_serializers.BomItemSerializer
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
if request.is_ajax():
return JsonResponse(data, safe=False)
else:
return Response(data)
def get_serializer(self, *args, **kwargs): def get_serializer(self, *args, **kwargs):
# Do we wish to include extra detail? # Do we wish to include extra detail?
@ -622,8 +635,10 @@ class BomList(generics.ListCreateAPIView):
return self.serializer_class(*args, **kwargs) return self.serializer_class(*args, **kwargs)
def get_queryset(self): def get_queryset(self, *args, **kwargs):
queryset = BomItem.objects.all() queryset = BomItem.objects.all()
queryset = self.get_serializer_class().setup_eager_loading(queryset) queryset = self.get_serializer_class().setup_eager_loading(queryset)
return queryset return queryset

View File

@ -236,6 +236,9 @@ class PartSerializer(InvenTreeModelSerializer):
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
starred = serializers.SerializerMethodField() starred = serializers.SerializerMethodField()
# PrimaryKeyRelated fields (Note: enforcing field type here results in much faster queries, somehow...)
category = serializers.PrimaryKeyRelatedField(queryset=PartCategory.objects.all())
# TODO - Include annotation for the following fields: # TODO - Include annotation for the following fields:
# allocated_stock = serializers.FloatField(source='allocation_count', read_only=True) # allocated_stock = serializers.FloatField(source='allocation_count', read_only=True)
# bom_items = serializers.IntegerField(source='bom_count', read_only=True) # bom_items = serializers.IntegerField(source='bom_count', read_only=True)
@ -303,7 +306,12 @@ class BomItemSerializer(InvenTreeModelSerializer):
quantity = serializers.FloatField() quantity = serializers.FloatField()
part = serializers.PrimaryKeyRelatedField(queryset=Part.objects.filter(assembly=True))
part_detail = PartBriefSerializer(source='part', many=False, read_only=True) part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
sub_part = serializers.PrimaryKeyRelatedField(queryset=Part.objects.filter(component=True))
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True) sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
validated = serializers.BooleanField(read_only=True, source='is_line_valid') validated = serializers.BooleanField(read_only=True, source='is_line_valid')
@ -328,6 +336,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
queryset = queryset.prefetch_related('part') queryset = queryset.prefetch_related('part')
queryset = queryset.prefetch_related('part__category') queryset = queryset.prefetch_related('part__category')
queryset = queryset.prefetch_related('part__stock_items') queryset = queryset.prefetch_related('part__stock_items')
queryset = queryset.prefetch_related('sub_part') queryset = queryset.prefetch_related('sub_part')
queryset = queryset.prefetch_related('sub_part__category') queryset = queryset.prefetch_related('sub_part__category')
queryset = queryset.prefetch_related('sub_part__stock_items') queryset = queryset.prefetch_related('sub_part__stock_items')

View File

@ -338,11 +338,6 @@ class StockList(generics.ListCreateAPIView):
queryset = self.filter_queryset(self.get_queryset()) queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
data = serializer.data data = serializer.data
@ -363,6 +358,7 @@ class StockList(generics.ListCreateAPIView):
part_ids.add(part) part_ids.add(part)
sp = item['supplier_part'] sp = item['supplier_part']
if sp: if sp:
supplier_part_ids.add(sp) supplier_part_ids.add(sp)
@ -434,6 +430,7 @@ class StockList(generics.ListCreateAPIView):
def get_queryset(self, *args, **kwargs): def get_queryset(self, *args, **kwargs):
queryset = super().get_queryset(*args, **kwargs) queryset = super().get_queryset(*args, **kwargs)
queryset = StockItemSerializer.prefetch_queryset(queryset) queryset = StockItemSerializer.prefetch_queryset(queryset)
queryset = StockItemSerializer.annotate_queryset(queryset) queryset = StockItemSerializer.annotate_queryset(queryset)

View File

@ -99,15 +99,34 @@ class StockItemSerializer(InvenTreeModelSerializer):
return queryset return queryset
belongs_to = serializers.PrimaryKeyRelatedField(read_only=True)
build_order = serializers.PrimaryKeyRelatedField(read_only=True)
customer = serializers.PrimaryKeyRelatedField(read_only=True)
location = serializers.PrimaryKeyRelatedField(read_only=True)
in_stock = serializers.BooleanField(read_only=True)
sales_order = serializers.PrimaryKeyRelatedField(read_only=True)
status_text = serializers.CharField(source='get_status_display', read_only=True) status_text = serializers.CharField(source='get_status_display', read_only=True)
part_detail = PartBriefSerializer(source='part', many=False, read_only=True) supplier_part = serializers.PrimaryKeyRelatedField(read_only=True)
location_detail = LocationBriefSerializer(source='location', many=False, read_only=True)
supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True) supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True)
part = serializers.PrimaryKeyRelatedField(read_only=True)
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
location_detail = LocationBriefSerializer(source='location', many=False, read_only=True)
tracking_items = serializers.IntegerField(source='tracking_info_count', read_only=True, required=False) tracking_items = serializers.IntegerField(source='tracking_info_count', read_only=True, required=False)
quantity = serializers.FloatField() quantity = serializers.FloatField()
allocated = serializers.FloatField(source='allocation_count', required=False) allocated = serializers.FloatField(source='allocation_count', required=False)
serial = serializers.IntegerField(required=False) serial = serializers.IntegerField(required=False)
@ -140,9 +159,9 @@ class StockItemSerializer(InvenTreeModelSerializer):
fields = [ fields = [
'allocated', 'allocated',
'batch', 'batch',
'build_order',
'belongs_to', 'belongs_to',
'customer', 'customer',
'build_order',
'in_stock', 'in_stock',
'link', 'link',
'location', 'location',
@ -155,10 +174,10 @@ class StockItemSerializer(InvenTreeModelSerializer):
'required_tests', 'required_tests',
'sales_order', 'sales_order',
'serial', 'serial',
'supplier_part',
'supplier_part_detail',
'status', 'status',
'status_text', 'status_text',
'supplier_part',
'supplier_part_detail',
'tracking_items', 'tracking_items',
'uid', 'uid',
] ]