model_train_dm/backend/apps/algorithms/views/algorithm.py

233 lines
8.6 KiB
Python
Raw Normal View History

2026-07-27 17:51:49 +08:00
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)