From 8211a33b58a01d7a80884738ec0e833d7e3b721f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 28 Nov 2025 15:57:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20material=20list=20filter=20low=5Finm?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mtm/filters.py | 8 +++----- apps/mtm/models.py | 23 ++++++++++++++++++++++- apps/mtm/serializers.py | 8 +++++--- apps/mtm/views.py | 18 +----------------- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/apps/mtm/filters.py b/apps/mtm/filters.py index 138b48de..08d67141 100644 --- a/apps/mtm/filters.py +++ b/apps/mtm/filters.py @@ -2,13 +2,11 @@ from django_filters import rest_framework as filters from apps.mtm.models import Goal, Material, Route, RoutePack 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:库存不足") - count__gt = filters.NumberFilter(field_name='count', lookup_expr='gt') - count_mb__gt = filters.NumberFilter(field_name='count_mb', lookup_expr='gt') - count_wm__gt = filters.NumberFilter(field_name='count_wm', lookup_expr='gt') class Meta: model = Material @@ -30,7 +28,7 @@ class MaterialFilter(filters.FilterSet): def filter_tag(self, queryset, name, value): if value == 'low_inm': - queryset = queryset.exclude(count_safe=None).exclude(count_safe__lte=0).filter( + queryset = Material.annotate_count(queryset.exclude(count_safe=None).exclude(count_safe__lte=0)).filter( count__lte=F('count_safe')) return queryset diff --git a/apps/mtm/models.py b/apps/mtm/models.py index c81b87ed..8746b87d 100644 --- a/apps/mtm/models.py +++ b/apps/mtm/models.py @@ -6,6 +6,8 @@ from collections import defaultdict, deque from django.db.models import Q from datetime import datetime, timedelta from django.utils import timezone +from django.db.models import Sum, Q, Value, F, ExpressionWrapper, DecimalField +from django.db.models.functions import Coalesce class Process(CommonBModel): """ @@ -123,7 +125,26 @@ class Material(CommonAModel): def fname(self): return f'{self.name}|{self.specification if self.specification else ""}|{self.model if self.model else ""}|{self.process.name if self.process else ""}' - + @staticmethod + def annotate_count(qs): + return qs.annotate( + count_mb=Coalesce( + Sum('mb_m__count', filter=Q(mb_m__state=10, mb_m__count__gt=0)), + Value(0), + output_field=DecimalField() + ), + count_wm=Coalesce( + Sum('wm_m__count', filter=Q(wm_m__state=10, wm_m__count__gt=0)), + Value(0), + output_field=DecimalField() + ) + ).annotate( + count=ExpressionWrapper( + F('count_wm') + F('count_mb'), + output_field=DecimalField() + ) + ) + class Shift(CommonBModel): """TN:班次 """ diff --git a/apps/mtm/serializers.py b/apps/mtm/serializers.py index db0877e3..f7ccf8d8 100644 --- a/apps/mtm/serializers.py +++ b/apps/mtm/serializers.py @@ -38,13 +38,15 @@ class MaterialSerializer(CustomModelSerializer): count = serializers.SerializerMethodField() def get_count_mb(self, obj): - return getattr(obj, 'count_mb', 0) + return getattr(obj, 'count_mb', None) def get_count_wm(self, obj): - return getattr(obj, 'count_wm', 0) + return getattr(obj, 'count_wm', None) def get_count(self, obj): - return getattr(obj, 'count_mb', 0) + getattr(obj, 'count_wm', 0) + if hasattr(obj, 'count_mb') and hasattr(obj, 'count_wm'): + return getattr(obj, 'count_mb', 0) + getattr(obj, 'count_wm', 0) + return None class Meta: model = Material diff --git a/apps/mtm/views.py b/apps/mtm/views.py index de340349..27632473 100644 --- a/apps/mtm/views.py +++ b/apps/mtm/views.py @@ -45,23 +45,7 @@ class MaterialViewSet(CustomModelViewSet): def get_queryset(self): qs = super().get_queryset() if self.action in ["list", "retrieve"] and self.request.query_params.get('wiith_count', None) == 'yes': - return qs.annotate( - count_mb=Coalesce( - Sum('mb_m__count', filter=Q(mb_m__state=10, mb_m__count___gt=0)), - Value(0), - output_field=DecimalField() - ), - count_wm=Coalesce( - Sum('wm_m__count', filter=Q(wm_m__state=10, wm_m__count___gt=0)), - Value(0), - output_field=DecimalField() - ) - ).annotate( - count=ExpressionWrapper( - F('count_wm') + F('count_mb'), - output_field=DecimalField() - ) - ) + return Material.annotate_count(qs) return qs def perform_destroy(self, instance):