perf: 优化 Material 可用物料过滤,改为 DB 子查询

- 新增 filter_process_todo 过滤器替代原 todo tag 逻辑
- 避免将 ID 列表加载到 Python 内存,改用两个子查询 OR 合并

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-03-27 14:40:07 +08:00
parent 68191dc305
commit b3d0b34719
1 changed files with 11 additions and 2 deletions

View File

@ -1,12 +1,13 @@
from django_filters import rest_framework as filters
from apps.mtm.models import Goal, Material, Route, RoutePack
from apps.mtm.models import Goal, Material, Route, RouteMat, RoutePack, Process
from django.db.models.expressions import F
from rest_framework.exceptions import ParseError
from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField
from django.db.models.functions import Coalesce
class MaterialFilter(filters.FilterSet):
tag = filters.CharFilter(method='filter_tag', label="low_inm:库存不足")
tag = filters.CharFilter(method='filter_tag', label="low_inm:库存不足;todo:可用")
process_todo = filters.CharFilter(method='filter_process_todo', label="process_todo:待处理")
class Meta:
model = Material
@ -25,6 +26,14 @@ class MaterialFilter(filters.FilterSet):
"route_material_out__mgroup": ["exact"],
"count_safe": ["gte", "lte", "exact", "gt", "lt"]
}
def filter_process_todo(self, queryset, name, value):
if value:
queryset = queryset.filter(
Q(id__in=RouteMat.objects.filter(route__process__id=value).values('material_id')) |
Q(id__in=Route.objects.filter(process__id=value).values('material_in_id'))
)
return queryset
def filter_tag(self, queryset, name, value):
if value == 'low_inm':