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"""
 | 
			
		||||
        queryset = super().get_queryset()
 | 
			
		||||
 | 
			
		||||
        queryset = queryset.select_related(
 | 
			
		||||
            'build', 'bom_item',
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        queryset = build.serializers.BuildLineSerializer.annotate_queryset(queryset)
 | 
			
		||||
 | 
			
		||||
        return queryset
 | 
			
		||||
 
 | 
			
		||||
@@ -1012,7 +1012,7 @@ class BuildItemSerializer(InvenTreeModelSerializer):
 | 
			
		||||
    build = serializers.PrimaryKeyRelatedField(source='build_line.build', many=False, read_only=True)
 | 
			
		||||
 | 
			
		||||
    # 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)
 | 
			
		||||
    location_detail = LocationSerializer(source='stock_item.location', 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()
 | 
			
		||||
 | 
			
		||||
    # Foreign key fields
 | 
			
		||||
    bom_item_detail = BomItemSerializer(source='bom_item', many=False, read_only=True)
 | 
			
		||||
    part_detail = PartSerializer(source='bom_item.sub_part', 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, pricing=False)
 | 
			
		||||
    allocations = BuildItemSerializer(many=True, read_only=True)
 | 
			
		||||
 | 
			
		||||
    # Annotated (calculated) fields
 | 
			
		||||
@@ -1094,16 +1094,28 @@ class BuildLineSerializer(InvenTreeModelSerializer):
 | 
			
		||||
        - on_order: Total stock on order for this build line
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        queryset = queryset.select_related(
 | 
			
		||||
            'build', 'bom_item',
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # Pre-fetch related fields
 | 
			
		||||
        queryset = queryset.prefetch_related(
 | 
			
		||||
            'bom_item__sub_part',
 | 
			
		||||
            'bom_item__sub_part__stock_items',
 | 
			
		||||
            'bom_item__sub_part__stock_items__allocations',
 | 
			
		||||
            'bom_item__sub_part__stock_items__sales_order_allocations',
 | 
			
		||||
            'bom_item__sub_part__tags',
 | 
			
		||||
 | 
			
		||||
            'bom_item__substitutes',
 | 
			
		||||
            'bom_item__substitutes__part__stock_items',
 | 
			
		||||
            'bom_item__substitutes__part__stock_items__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
 | 
			
		||||
 
 | 
			
		||||
@@ -284,6 +284,17 @@ class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
			
		||||
            '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)
 | 
			
		||||
 | 
			
		||||
    # Pricing fields
 | 
			
		||||
@@ -532,6 +543,7 @@ class PartSerializer(InvenTree.serializers.RemoteImageMixin, InvenTree.serialize
 | 
			
		||||
        category_detail = kwargs.pop('category_detail', False)
 | 
			
		||||
        parameters = kwargs.pop('parameters', False)
 | 
			
		||||
        create = kwargs.pop('create', False)
 | 
			
		||||
        pricing = kwargs.pop('pricing', True)
 | 
			
		||||
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
@@ -546,6 +558,10 @@ class PartSerializer(InvenTree.serializers.RemoteImageMixin, InvenTree.serialize
 | 
			
		||||
            for f in self.skip_create_fields()[1:]:
 | 
			
		||||
                self.fields.pop(f)
 | 
			
		||||
 | 
			
		||||
        if not pricing:
 | 
			
		||||
            self.fields.pop('pricing_min')
 | 
			
		||||
            self.fields.pop('pricing_max')
 | 
			
		||||
 | 
			
		||||
    def get_api_url(self):
 | 
			
		||||
        """Return the API url associated with this serializer"""
 | 
			
		||||
        return reverse_lazy('api-part-list')
 | 
			
		||||
@@ -1087,7 +1103,7 @@ class BomItemSubstituteSerializer(InvenTree.serializers.InvenTreeModelSerializer
 | 
			
		||||
            '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):
 | 
			
		||||
@@ -1132,15 +1148,20 @@ class BomItemSerializer(InvenTree.serializers.InvenTreeModelSerializer):
 | 
			
		||||
        """
 | 
			
		||||
        part_detail = kwargs.pop('part_detail', False)
 | 
			
		||||
        sub_part_detail = kwargs.pop('sub_part_detail', False)
 | 
			
		||||
        pricing = kwargs.pop('pricing', True)
 | 
			
		||||
 | 
			
		||||
        super(BomItemSerializer, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        if part_detail is not True:
 | 
			
		||||
        if not 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')
 | 
			
		||||
 | 
			
		||||
        if not pricing:
 | 
			
		||||
            self.fields.pop('pricing_min')
 | 
			
		||||
            self.fields.pop('pricing_max')
 | 
			
		||||
 | 
			
		||||
    quantity = InvenTree.serializers.InvenTreeDecimalField(required=True)
 | 
			
		||||
 | 
			
		||||
    def validate_quantity(self, quantity):
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user