perf:mlog/handover/mlogb列表消除N+1,select_related精简改prefetch,修Handover.handoverb属性绕过prefetch的bug
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
45c61efdc6
commit
5881c32c38
|
|
@ -721,7 +721,8 @@ class Handover(CommonADModel):
|
|||
|
||||
@property
|
||||
def handoverb(self):
|
||||
return Handoverb.objects.filter(handover=self)
|
||||
# 用反向关联管理器, 以命中 list 接口的 Prefetch("b_handover") 缓存, 避免 N+1
|
||||
return self.b_handover.all()
|
||||
|
||||
class Handoverb(BaseModel):
|
||||
"""TN: 子级交接记录
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ class MlogViewSet(CustomModelViewSet):
|
|||
"handle_user",
|
||||
"equipment",
|
||||
"mgroup",
|
||||
"mgroup__belong_dept",
|
||||
"material_in",
|
||||
"material_out",
|
||||
"material_in__process",
|
||||
|
|
@ -298,7 +299,22 @@ class MlogViewSet(CustomModelViewSet):
|
|||
# 'equipment_2', 'material_in', 'material_out', 'route__routepack', 'submit_user',
|
||||
# 'supplier', 'ticket', 'mgroup__process', 'test_user', 'handle_leader', 'test_user', 'team',
|
||||
# 'material_in__process', 'material_out__process', "shift", "route"]
|
||||
prefetch_related_fields = ["handle_users", "material_outs", "equipments"]
|
||||
prefetch_related_fields = [
|
||||
"handle_users",
|
||||
"material_outs",
|
||||
"equipments",
|
||||
# 以下为可选的一对一/外键, 用 prefetch(每个关系仅 1 条 IN 查询)避免 N+1
|
||||
# 又不加宽主查询的 JOIN
|
||||
"team",
|
||||
"supplier",
|
||||
"mtask",
|
||||
"shift",
|
||||
"test_user",
|
||||
"handle_user_2",
|
||||
"handle_leader",
|
||||
"equipment_2",
|
||||
"ticket__state",
|
||||
]
|
||||
filterset_class = MlogFilter
|
||||
search_fields = [
|
||||
"material_in__name",
|
||||
|
|
@ -342,27 +358,7 @@ class MlogViewSet(CustomModelViewSet):
|
|||
]
|
||||
)
|
||||
def list(self, request, *args, **kwargs):
|
||||
from django.db import connection
|
||||
from django.conf import settings
|
||||
|
||||
# 清空之前的查询记录
|
||||
connection.queries_log.clear()
|
||||
|
||||
# 调用父类的 list 方法
|
||||
response = super().list(request, *args, **kwargs)
|
||||
|
||||
# 获取执行的 SQL 查询
|
||||
queries = connection.queries
|
||||
sql_queries = []
|
||||
|
||||
for query in queries:
|
||||
sql_queries.append({"sql": query["sql"], "time": query["time"], "params": query.get("params", [])})
|
||||
|
||||
# 将 SQL 信息添加到响应中(仅在调试模式)
|
||||
if settings.DEBUG:
|
||||
response.data["_debug"] = {"sql_queries": sql_queries, "total_queries": len(queries), "total_time": sum(float(q["time"]) for q in queries)}
|
||||
|
||||
return response
|
||||
return super().list(request, *args, **kwargs)
|
||||
|
||||
def add_info_for_list(self, data):
|
||||
czx_dict = {}
|
||||
|
|
@ -590,10 +586,10 @@ class HandoverViewSet(CustomModelViewSet):
|
|||
queryset = Handover.objects.all()
|
||||
list_serializer_class = HandoverListSerializer
|
||||
serializer_class = HandoverSerializer
|
||||
select_related_fields = ["send_user", "send_mgroup", "send_dept", "recive_user", "recive_mgroup", "recive_dept", "wm", "material_changed", "material"]
|
||||
select_related_fields = ["send_user", "send_mgroup", "send_dept", "recive_user", "recive_mgroup", "recive_dept", "wm", "material_changed", "material", "material__process"]
|
||||
filterset_class = HandoverFilter
|
||||
search_fields = ["material__name", "material__number", "material__specification", "batch", "material__model", "b_handover__batch", "new_batch", "wm__batch"]
|
||||
prefetch_related_fields = [Prefetch("b_handover", queryset=Handoverb.objects.select_related("wm__defect"))]
|
||||
prefetch_related_fields = [Prefetch("b_handover", queryset=Handoverb.objects.select_related("wm__defect")), "ticket__state"]
|
||||
|
||||
def perform_destroy(self, instance: Handover):
|
||||
user = self.request.user
|
||||
|
|
@ -782,7 +778,7 @@ class MlogbViewSet(CustomListModelMixin, CustomGenericViewSet):
|
|||
perms_map = {"get": "*"}
|
||||
queryset = Mlogb.objects.all()
|
||||
serializer_class = MlogbDetailSerializer
|
||||
select_related_fields = ["material_out", "material_in", "test_user", "wm_in__defect"]
|
||||
select_related_fields = ["material_out", "material_out__process", "material_in", "material_in__process", "test_user", "wm_in__defect"]
|
||||
prefetch_related_fields = [
|
||||
Prefetch("mlogbdefect_set", queryset=MlogbDefect.objects.select_related("defect")),
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue