mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
commit
8eeb88a0ea
@ -361,7 +361,6 @@ class PartDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
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 = part_serializers.PartSerializer.prefetch_queryset(queryset)
|
|
||||||
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)
|
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
@ -619,8 +618,6 @@ class PartList(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 = part_serializers.PartSerializer.prefetch_queryset(queryset)
|
|
||||||
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)
|
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
@ -633,10 +630,6 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
params = self.request.query_params
|
params = self.request.query_params
|
||||||
|
|
||||||
# Annotate calculated data to the queryset
|
|
||||||
# (This will be used for further filtering)
|
|
||||||
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)
|
|
||||||
|
|
||||||
queryset = super().filter_queryset(queryset)
|
queryset = super().filter_queryset(queryset)
|
||||||
|
|
||||||
# Filter by "uses" query - Limit to parts which use the provided part
|
# Filter by "uses" query - Limit to parts which use the provided part
|
||||||
|
@ -27,6 +27,7 @@ from markdownx.models import MarkdownxField
|
|||||||
from django_cleanup import cleanup
|
from django_cleanup import cleanup
|
||||||
|
|
||||||
from mptt.models import TreeForeignKey, MPTTModel
|
from mptt.models import TreeForeignKey, MPTTModel
|
||||||
|
from mptt.managers import TreeManager
|
||||||
|
|
||||||
from stdimage.models import StdImageField
|
from stdimage.models import StdImageField
|
||||||
|
|
||||||
@ -284,6 +285,24 @@ def match_part_names(match, threshold=80, reverse=True, compare_length=False):
|
|||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
|
||||||
|
class PartManager(TreeManager):
|
||||||
|
"""
|
||||||
|
Defines a custom object manager for the Part model.
|
||||||
|
|
||||||
|
The main purpose of this manager is to reduce the number of database hits,
|
||||||
|
as the Part model has a large number of ForeignKey fields!
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
|
||||||
|
return super().get_queryset().prefetch_related(
|
||||||
|
'category',
|
||||||
|
'category__parent',
|
||||||
|
'stock_items',
|
||||||
|
'builds',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@cleanup.ignore
|
@cleanup.ignore
|
||||||
class Part(MPTTModel):
|
class Part(MPTTModel):
|
||||||
""" The Part object represents an abstract part, the 'concept' of an actual entity.
|
""" The Part object represents an abstract part, the 'concept' of an actual entity.
|
||||||
@ -321,6 +340,8 @@ class Part(MPTTModel):
|
|||||||
responsible: User who is responsible for this part (optional)
|
responsible: User who is responsible for this part (optional)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
objects = PartManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Part")
|
verbose_name = _("Part")
|
||||||
verbose_name_plural = _("Parts")
|
verbose_name_plural = _("Parts")
|
||||||
|
@ -215,25 +215,6 @@ class PartSerializer(InvenTreeModelSerializer):
|
|||||||
if category_detail is not True:
|
if category_detail is not True:
|
||||||
self.fields.pop('category_detail')
|
self.fields.pop('category_detail')
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def prefetch_queryset(queryset):
|
|
||||||
"""
|
|
||||||
Prefetch related database tables,
|
|
||||||
to reduce database hits.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return queryset.prefetch_related(
|
|
||||||
'category',
|
|
||||||
'category__parts',
|
|
||||||
'category__parent',
|
|
||||||
'stock_items',
|
|
||||||
'bom_items',
|
|
||||||
'builds',
|
|
||||||
'supplier_parts',
|
|
||||||
'supplier_parts__purchase_order_line_items',
|
|
||||||
'supplier_parts__purchase_order_line_items__order',
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def annotate_queryset(queryset):
|
def annotate_queryset(queryset):
|
||||||
"""
|
"""
|
||||||
|
@ -99,7 +99,7 @@ class CategoryTest(TestCase):
|
|||||||
""" Test that the Category parameters are correctly fetched """
|
""" Test that the Category parameters are correctly fetched """
|
||||||
|
|
||||||
# Check number of SQL queries to iterate other parameters
|
# Check number of SQL queries to iterate other parameters
|
||||||
with self.assertNumQueries(3):
|
with self.assertNumQueries(7):
|
||||||
# Prefetch: 3 queries (parts, parameters and parameters_template)
|
# Prefetch: 3 queries (parts, parameters and parameters_template)
|
||||||
fasteners = self.fasteners.prefetch_parts_parameters()
|
fasteners = self.fasteners.prefetch_parts_parameters()
|
||||||
# Iterate through all parts and parameters
|
# Iterate through all parts and parameters
|
||||||
|
@ -84,7 +84,6 @@ class StockDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
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.annotate_queryset(queryset)
|
queryset = StockItemSerializer.annotate_queryset(queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
@ -637,7 +636,6 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
queryset = super().get_queryset(*args, **kwargs)
|
queryset = super().get_queryset(*args, **kwargs)
|
||||||
|
|
||||||
queryset = StockItemSerializer.prefetch_queryset(queryset)
|
|
||||||
queryset = StockItemSerializer.annotate_queryset(queryset)
|
queryset = StockItemSerializer.annotate_queryset(queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -23,6 +23,7 @@ from django.dispatch import receiver
|
|||||||
from markdownx.models import MarkdownxField
|
from markdownx.models import MarkdownxField
|
||||||
|
|
||||||
from mptt.models import MPTTModel, TreeForeignKey
|
from mptt.models import MPTTModel, TreeForeignKey
|
||||||
|
from mptt.managers import TreeManager
|
||||||
|
|
||||||
from decimal import Decimal, InvalidOperation
|
from decimal import Decimal, InvalidOperation
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
@ -130,6 +131,31 @@ def before_delete_stock_location(sender, instance, using, **kwargs):
|
|||||||
child.save()
|
child.save()
|
||||||
|
|
||||||
|
|
||||||
|
class StockItemManager(TreeManager):
|
||||||
|
"""
|
||||||
|
Custom database manager for the StockItem class.
|
||||||
|
|
||||||
|
StockItem querysets will automatically prefetch related fields.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
|
||||||
|
return super().get_queryset().prefetch_related(
|
||||||
|
'belongs_to',
|
||||||
|
'build',
|
||||||
|
'customer',
|
||||||
|
'purchase_order',
|
||||||
|
'sales_order',
|
||||||
|
'supplier_part',
|
||||||
|
'supplier_part__supplier',
|
||||||
|
'allocations',
|
||||||
|
'sales_order_allocations',
|
||||||
|
'location',
|
||||||
|
'part',
|
||||||
|
'tracking_info'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StockItem(MPTTModel):
|
class StockItem(MPTTModel):
|
||||||
"""
|
"""
|
||||||
A StockItem object represents a quantity of physical instances of a part.
|
A StockItem object represents a quantity of physical instances of a part.
|
||||||
|
@ -70,29 +70,6 @@ class StockItemSerializer(InvenTreeModelSerializer):
|
|||||||
- Includes serialization for the item location
|
- Includes serialization for the item location
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def prefetch_queryset(queryset):
|
|
||||||
"""
|
|
||||||
Prefetch related database tables,
|
|
||||||
to reduce database hits.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return queryset.prefetch_related(
|
|
||||||
'belongs_to',
|
|
||||||
'build',
|
|
||||||
'customer',
|
|
||||||
'purchase_order',
|
|
||||||
'sales_order',
|
|
||||||
'supplier_part',
|
|
||||||
'supplier_part__supplier',
|
|
||||||
'supplier_part__manufacturer_part__manufacturer',
|
|
||||||
'allocations',
|
|
||||||
'sales_order_allocations',
|
|
||||||
'location',
|
|
||||||
'part',
|
|
||||||
'tracking_info',
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def annotate_queryset(queryset):
|
def annotate_queryset(queryset):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user