mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-13 10:33:07 +00:00
* Allow part category table to be ordered by part count * Add queryset annotation for part-category part-count - Uses subquery to annotate the part-count for sub-categories - Huge reduction in number of queries * Update 'pathstring' property of PartCategory and StockLocation - No longer a dynamically calculated value - Constructed when the model is saved, and then written to the database - Limited to 250 characters * Data migration to re-construct pathstring for PartCategory objects * Fix for tree model save() method * Add unit tests for pathstring construction * Data migration for StockLocation pathstring values * Update part API - Add new annotation to PartLocationDetail view * Update API version * Apply similar annotation to StockLocation API endpoints * Extra tests for PartCategory API * Unit test fixes * Allow PartCategory and StockLocation lists to be sorted by 'pathstring' * Further unit test fixes
37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
"""Custom query filters for the Stock models"""
|
|
|
|
from django.db.models import F, Func, IntegerField, OuterRef, Q, Subquery
|
|
from django.db.models.functions import Coalesce
|
|
|
|
import stock.models
|
|
|
|
|
|
def annotate_location_items(filter: Q = None):
|
|
"""Construct a queryset annotation which returns the number of stock items in a particular location.
|
|
|
|
- Includes items in subcategories also
|
|
- Requires subquery to perform annotation
|
|
"""
|
|
|
|
# Construct a subquery to provide all items in this location and any sublocations
|
|
subquery = stock.models.StockItem.objects.exclude(location=None).filter(
|
|
location__tree_id=OuterRef('tree_id'),
|
|
location__lft__gte=OuterRef('lft'),
|
|
location__rght__lte=OuterRef('rght'),
|
|
location__level__gte=OuterRef('level'),
|
|
)
|
|
|
|
# Optionally apply extra filter to returned results
|
|
if filter is not None:
|
|
subquery = subquery.filter(filter)
|
|
|
|
return Coalesce(
|
|
Subquery(
|
|
subquery.annotate(
|
|
total=Func(F('pk'), function='COUNT', output_field=IntegerField())
|
|
).values('total')
|
|
),
|
|
0,
|
|
output_field=IntegerField()
|
|
)
|