mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 07:05:41 +00:00 
			
		
		
		
	Query improvements for BuildLine table (#5153)
- Prefetch / preselect related records - Improve query speed
This commit is contained in:
		@@ -308,10 +308,6 @@ class BuildLineEndpoint:
 | 
				
			|||||||
        """Override queryset to select-related and annotate"""
 | 
					        """Override queryset to select-related and annotate"""
 | 
				
			||||||
        queryset = super().get_queryset()
 | 
					        queryset = super().get_queryset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        queryset = queryset.select_related(
 | 
					 | 
				
			||||||
            'build', 'bom_item',
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        queryset = build.serializers.BuildLineSerializer.annotate_queryset(queryset)
 | 
					        queryset = build.serializers.BuildLineSerializer.annotate_queryset(queryset)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return queryset
 | 
					        return queryset
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1012,7 +1012,7 @@ class BuildItemSerializer(InvenTreeModelSerializer):
 | 
				
			|||||||
    build = serializers.PrimaryKeyRelatedField(source='build_line.build', many=False, read_only=True)
 | 
					    build = serializers.PrimaryKeyRelatedField(source='build_line.build', many=False, read_only=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Extra (optional) detail fields
 | 
					    # Extra (optional) detail fields
 | 
				
			||||||
    part_detail = PartBriefSerializer(source='stock_item.part', many=False, read_only=True)
 | 
					    part_detail = PartBriefSerializer(source='stock_item.part', many=False, read_only=True, pricing=False)
 | 
				
			||||||
    stock_item_detail = StockItemSerializerBrief(source='stock_item', read_only=True)
 | 
					    stock_item_detail = StockItemSerializerBrief(source='stock_item', read_only=True)
 | 
				
			||||||
    location_detail = LocationSerializer(source='stock_item.location', read_only=True)
 | 
					    location_detail = LocationSerializer(source='stock_item.location', read_only=True)
 | 
				
			||||||
    build_detail = BuildSerializer(source='build_line.build', many=False, read_only=True)
 | 
					    build_detail = BuildSerializer(source='build_line.build', many=False, read_only=True)
 | 
				
			||||||
@@ -1074,8 +1074,8 @@ class BuildLineSerializer(InvenTreeModelSerializer):
 | 
				
			|||||||
    quantity = serializers.FloatField()
 | 
					    quantity = serializers.FloatField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Foreign key fields
 | 
					    # Foreign key fields
 | 
				
			||||||
    bom_item_detail = BomItemSerializer(source='bom_item', many=False, read_only=True)
 | 
					    bom_item_detail = BomItemSerializer(source='bom_item', many=False, read_only=True, pricing=False)
 | 
				
			||||||
    part_detail = PartSerializer(source='bom_item.sub_part', many=False, read_only=True)
 | 
					    part_detail = PartSerializer(source='bom_item.sub_part', many=False, read_only=True, pricing=False)
 | 
				
			||||||
    allocations = BuildItemSerializer(many=True, read_only=True)
 | 
					    allocations = BuildItemSerializer(many=True, read_only=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Annotated (calculated) fields
 | 
					    # Annotated (calculated) fields
 | 
				
			||||||
@@ -1094,16 +1094,28 @@ class BuildLineSerializer(InvenTreeModelSerializer):
 | 
				
			|||||||
        - on_order: Total stock on order for this build line
 | 
					        - on_order: Total stock on order for this build line
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        queryset = queryset.select_related(
 | 
				
			||||||
 | 
					            'build', 'bom_item',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Pre-fetch related fields
 | 
					        # Pre-fetch related fields
 | 
				
			||||||
        queryset = queryset.prefetch_related(
 | 
					        queryset = queryset.prefetch_related(
 | 
				
			||||||
 | 
					            'bom_item__sub_part',
 | 
				
			||||||
            'bom_item__sub_part__stock_items',
 | 
					            'bom_item__sub_part__stock_items',
 | 
				
			||||||
            'bom_item__sub_part__stock_items__allocations',
 | 
					            'bom_item__sub_part__stock_items__allocations',
 | 
				
			||||||
            'bom_item__sub_part__stock_items__sales_order_allocations',
 | 
					            'bom_item__sub_part__stock_items__sales_order_allocations',
 | 
				
			||||||
 | 
					            'bom_item__sub_part__tags',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            'bom_item__substitutes',
 | 
					            'bom_item__substitutes',
 | 
				
			||||||
            'bom_item__substitutes__part__stock_items',
 | 
					            'bom_item__substitutes__part__stock_items',
 | 
				
			||||||
            'bom_item__substitutes__part__stock_items__allocations',
 | 
					            'bom_item__substitutes__part__stock_items__allocations',
 | 
				
			||||||
            'bom_item__substitutes__part__stock_items__sales_order_allocations',
 | 
					            'bom_item__substitutes__part__stock_items__sales_order_allocations',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            'allocations',
 | 
				
			||||||
 | 
					            'allocations__stock_item',
 | 
				
			||||||
 | 
					            'allocations__stock_item__part',
 | 
				
			||||||
 | 
					            'allocations__stock_item__location',
 | 
				
			||||||
 | 
					            'allocations__stock_item__location__tags',
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Annotate the "allocated" quantity
 | 
					        # Annotate the "allocated" quantity
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -284,6 +284,17 @@ class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
				
			|||||||
            'barcode_hash',
 | 
					            'barcode_hash',
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Custom initialization routine for the PartBrief serializer"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pricing = kwargs.pop('pricing', True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not pricing:
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_min')
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_max')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
 | 
					    thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Pricing fields
 | 
					    # Pricing fields
 | 
				
			||||||
@@ -532,6 +543,7 @@ class PartSerializer(InvenTree.serializers.RemoteImageMixin, InvenTree.serialize
 | 
				
			|||||||
        category_detail = kwargs.pop('category_detail', False)
 | 
					        category_detail = kwargs.pop('category_detail', False)
 | 
				
			||||||
        parameters = kwargs.pop('parameters', False)
 | 
					        parameters = kwargs.pop('parameters', False)
 | 
				
			||||||
        create = kwargs.pop('create', False)
 | 
					        create = kwargs.pop('create', False)
 | 
				
			||||||
 | 
					        pricing = kwargs.pop('pricing', True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -546,6 +558,10 @@ class PartSerializer(InvenTree.serializers.RemoteImageMixin, InvenTree.serialize
 | 
				
			|||||||
            for f in self.skip_create_fields()[1:]:
 | 
					            for f in self.skip_create_fields()[1:]:
 | 
				
			||||||
                self.fields.pop(f)
 | 
					                self.fields.pop(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not pricing:
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_min')
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_max')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_api_url(self):
 | 
					    def get_api_url(self):
 | 
				
			||||||
        """Return the API url associated with this serializer"""
 | 
					        """Return the API url associated with this serializer"""
 | 
				
			||||||
        return reverse_lazy('api-part-list')
 | 
					        return reverse_lazy('api-part-list')
 | 
				
			||||||
@@ -1087,7 +1103,7 @@ class BomItemSubstituteSerializer(InvenTree.serializers.InvenTreeModelSerializer
 | 
				
			|||||||
            'part_detail',
 | 
					            'part_detail',
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    part_detail = PartBriefSerializer(source='part', read_only=True, many=False)
 | 
					    part_detail = PartBriefSerializer(source='part', read_only=True, many=False, pricing=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BomItemSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
					class BomItemSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
				
			||||||
@@ -1132,15 +1148,20 @@ class BomItemSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        part_detail = kwargs.pop('part_detail', False)
 | 
					        part_detail = kwargs.pop('part_detail', False)
 | 
				
			||||||
        sub_part_detail = kwargs.pop('sub_part_detail', False)
 | 
					        sub_part_detail = kwargs.pop('sub_part_detail', False)
 | 
				
			||||||
 | 
					        pricing = kwargs.pop('pricing', True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super(BomItemSerializer, self).__init__(*args, **kwargs)
 | 
					        super(BomItemSerializer, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if part_detail is not True:
 | 
					        if not part_detail:
 | 
				
			||||||
            self.fields.pop('part_detail')
 | 
					            self.fields.pop('part_detail')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if sub_part_detail is not True:
 | 
					        if not sub_part_detail:
 | 
				
			||||||
            self.fields.pop('sub_part_detail')
 | 
					            self.fields.pop('sub_part_detail')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not pricing:
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_min')
 | 
				
			||||||
 | 
					            self.fields.pop('pricing_max')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    quantity = InvenTree.serializers.InvenTreeDecimalField(required=True)
 | 
					    quantity = InvenTree.serializers.InvenTreeDecimalField(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def validate_quantity(self, quantity):
 | 
					    def validate_quantity(self, quantity):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user