model_train_dm/backend/apps/algorithms/views/algorithm.py
2026-07-27 17:51:49 +08:00

233 lines
8.6 KiB
Python

import json
import uuid
from datetime import datetime
from django.db import connection, transaction
from django.db.models import CharField, Max
from django.db.models.functions import Cast
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from apps.common.serializers import (
AiAlgorithmCallLogSerializer,
AiAlgorithmEngineSerializer,
AiAlgorithmSerializer,
)
from apps.core.models import (
AiAlgorithm,
AiAlgorithmCallLog,
AiAlgorithmEngine,
AiAlgorithmModels,
AiAlgorithmOutput,
AiAlgorithmParams,
AiAlgorithmTrainRecords,
)
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def search_algorithm(request):
algorithm_code = request.GET.get("algorithm_code", None)
algorithm_name = request.GET.get("algorithm_name", None)
algorithm_class = request.GET.get("algorithm_class", None)
scenario = request.GET.get("scenario", None)
algorithm_type = request.GET.get("algorithm_type", None)
algorithm_status = request.GET.get("algorithm_status", None)
development_unit = request.GET.get("development_unit", None)
class_code = request.GET.get("class_code", None)
page_size = request.GET.get("page_size", None)
filter_kwargs = {}
if algorithm_code:
filter_kwargs["algorithm_code__icontains"] = algorithm_code
if algorithm_name:
filter_kwargs["algorithm_name__icontains"] = algorithm_name
if algorithm_class:
filter_kwargs["algorithm_class__exact"] = algorithm_class
if scenario:
filter_kwargs["scenario__icontains"] = scenario
if algorithm_type:
filter_kwargs["algorithm_type__exact"] = algorithm_type
if algorithm_status:
filter_kwargs["algorithm_status__exact"] = algorithm_status
if development_unit:
filter_kwargs["development_unit__icontains"] = development_unit
if class_code:
filter_kwargs["labels__icontains"] = class_code
algorithms = AiAlgorithm.objects.filter(**filter_kwargs).order_by("algorithm_code")
paginator = PageNumberPagination()
paginator.page_size = page_size or 10
result_page = paginator.paginate_queryset(algorithms, request)
serializer = AiAlgorithmSerializer(result_page, many=True)
return paginator.get_paginated_response(serializer.data)
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def get_algorithm_tree(request):
sql = """
SELECT
a.id AS id,
a.classcode AS code,
a.classname AS name,
a.parentid AS parentid
FROM
ai_algorithm_class a
UNION
SELECT
b.id AS id,
b.algorithm_code AS code,
b.algorithm_name AS name,
b.algorithm_class AS parentid
FROM
ai_algorithm b
ORDER BY code
"""
with connection.cursor() as cursor:
cursor.execute(sql)
result = cursor.fetchall()
keys = ["id", "code", "name", "parentid"]
data = [dict(zip(keys, row)) for row in result]
return Response(data)
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def get_algorithm_list(request):
algorithm_code = request.GET.get("algorithm_code", None)
algorithm_name = request.GET.get("algorithm_name", None)
algorithm_class = request.GET.get("algorithm_class", None)
filter_kwargs = {}
if algorithm_code:
filter_kwargs["algorithm_code__icontains"] = algorithm_code
if algorithm_name:
filter_kwargs["algorithm_name__icontains"] = algorithm_name
if algorithm_class:
filter_kwargs["algorithm_class__exact"] = algorithm_class
algorithms = AiAlgorithm.objects.filter(**filter_kwargs).order_by(
"algorithm_class", "algorithm_code"
)
serializer = AiAlgorithmSerializer(algorithms, many=True)
return Response(serializer.data)
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def get_algorithm_engines(request):
algorithmengines = AiAlgorithmEngine.objects.order_by("enginecode")
serializer = AiAlgorithmEngineSerializer(algorithmengines, many=True)
return Response(serializer.data)
@api_view(["POST"])
@permission_classes([IsAuthenticated])
@transaction.atomic
def add_algorithm(request):
data = request.data
data["id"] = str(uuid.uuid4())
data["creator"] = request.user.username if request.user.username else "creator"
data["create_time"] = datetime.now()
algorithm_class = data.get("algorithm_class")
algorithm_engine = data.get("algorithm_engine")
max_algorithm_code = AiAlgorithm.objects.filter(algorithm_class=algorithm_class).aggregate(
max_algorithm_code=Max(Cast("algorithm_code", CharField()))
).get("max_algorithm_code")
max_algorithm_code = int(max_algorithm_code) if max_algorithm_code is not None else 0
new_algorithm_code = f"{max_algorithm_code + 1:03}"
data["algorithm_code"] = new_algorithm_code
serializer = AiAlgorithmSerializer(data=data)
if serializer.is_valid():
serializer.save()
engine = get_object_or_404(AiAlgorithmEngine, id=algorithm_engine)
if engine.training_params_template:
try:
params = json.loads(engine.training_params_template)
params_to_save = [
AiAlgorithmParams(
id=str(uuid.uuid4()),
algorithm_id=data["id"],
param_class="01",
param_order=param.get("param_order"),
param_name=param.get("param_name"),
param_desc=param.get("param_desc"),
param_type=param.get("param_type"),
param_unit=param.get("param_unit"),
param_range=param.get("param_range"),
default_values=param.get("default_values"),
description=param.get("description"),
)
for param in params
]
AiAlgorithmParams.objects.bulk_create(params_to_save)
except json.JSONDecodeError as e:
return Response(
{"error": f"Invalid JSON in training_params_template: {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)
return Response({"message": "Algorithm added successfully"})
return Response(
{"error": "Invalid data", "details": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def read_algorithm(request):
algorithm_id = request.GET.get("id", None)
algorithm = get_object_or_404(AiAlgorithm, id=algorithm_id)
serializer = AiAlgorithmSerializer(algorithm)
return Response(serializer.data)
@api_view(["PUT"])
@permission_classes([IsAuthenticated])
def update_algorithm(request):
data = request.data
algorithm = get_object_or_404(AiAlgorithm, id=data.get("id"))
serializer = AiAlgorithmSerializer(instance=algorithm, data=data, partial=True)
if serializer.is_valid():
serializer.save()
return Response({"message": "Algorithm updated successfully"})
return Response(
{"error": "Invalid data", "details": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
@api_view(["DELETE"])
@permission_classes([IsAuthenticated])
@transaction.atomic
def delete_algorithm(request):
algorithm = get_object_or_404(AiAlgorithm, id=request.GET.get("id"))
model_count = AiAlgorithmModels.objects.filter(algorithm_id=algorithm.id).count()
if model_count > 0:
return Response({"warn": "该算法已经绑定了模型,请先删除算法模型!"}, status=status.HTTP_400_BAD_REQUEST)
train_count = AiAlgorithmTrainRecords.objects.filter(algorithm_id=algorithm.id).count()
if train_count > 0:
return Response(
{"warn": "该算法已经存在了模型训练记录,请先删除算法模型训练记录!"},
status=status.HTTP_400_BAD_REQUEST,
)
try:
AiAlgorithmParams.objects.filter(algorithm_id=algorithm.id).delete()
AiAlgorithmOutput.objects.filter(algorithm_id=algorithm.id).delete()
algorithm.delete()
return Response({"message": "算法删除成功"}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": f"算法删除失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)