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 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 django.db.models.expressions import F
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
class MaterialFilter(filters.FilterSet): 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: class Meta:
model = Material model = Material
@ -25,6 +26,14 @@ class MaterialFilter(filters.FilterSet):
"route_material_out__mgroup": ["exact"], "route_material_out__mgroup": ["exact"],
"count_safe": ["gte", "lte", "exact", "gt", "lt"] "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): def filter_tag(self, queryset, name, value):
if value == 'low_inm': if value == 'low_inm':