from apps.lyautocode.models.models_autocode import * from utils.jsonResponse import SuccessResponse,DetailResponse,ErrorResponse from utils.common import get_parameter_dic, ast_convert,starts_with_digit from utils.models import is_table_exists from rest_framework import serializers from utils.serializers import CustomModelSerializer from utils.viewset import CustomModelViewSet from utils.autocode.lygeneratecode import GenerateCode from django.db.models import Q from django.db import transaction from django.utils.autoreload import restart_with_reloader import logging logger = logging.getLogger(__name__) class LyAutoCodeSerializer(CustomModelSerializer): """ 代码生成 -序列化器 """ def to_representation(self, instance): # 序列化 ret = super().to_representation(instance) ret['column'] = ast_convert(ret['column']) # 可以保存的修改字段值的方法 ret['other_config'] = ast_convert(ret['other_config']) # 可以保存的修改字段值的方法 return ret class Meta: model = LyAutoCode read_only_fields = ["id"] fields = '__all__' class LyAutoCodeCreateUpdateSerializer(CustomModelSerializer): """ 代码生成 -序列化器 """ column = serializers.JSONField() other_config = serializers.JSONField() class Meta: model = LyAutoCode read_only_fields = ["id"] fields = '__all__' class LyAutoCodeViewSet(CustomModelViewSet): """ 后台代码生成 接口: """ queryset = LyAutoCode.objects.filter(is_delete=False).order_by('-create_datetime') serializer_class = LyAutoCodeSerializer create_serializer_class = LyAutoCodeCreateUpdateSerializer update_serializer_class = LyAutoCodeCreateUpdateSerializer search_fields = ('class_name','verbose_name','db_table') # 重写delete方法,并改为逻辑删除 def destroy(self, request, *args, **kwargs): real_delete = get_parameter_dic(request).get('real_delete',None) instance = self.get_object_list() if not real_delete: for i in range(len(instance)): instance[i].is_delete = True model = self.get_serializer().Meta.model model.objects.bulk_update(instance, fields=['is_delete']) return DetailResponse(msg="删除成功") else: for i in range(len(instance)): serializer = self.get_serializer(instance[i]) object = serializer.data if instance[i].is_mount: menu_instance = None if instance[i].menu: menu_instance = instance[i].menu GenerateCode().generate(object, True, menu_instance,True) self.perform_destroy(instance) return DetailResponse(msg="删除成功") def create(self, request, *args, **kwargs): params = request.data class_name = params.get('class_name',None) if starts_with_digit(class_name): return ErrorResponse(msg="类名【%s】不能以数字开头!!!"%class_name) db_table = params.get('db_table', None) if self.filter_queryset(self.get_queryset()).filter(Q(class_name=class_name)|Q(db_table=db_table)).exists(): return ErrorResponse(msg="存在同名的类名或表名") if is_table_exists(db_table): return ErrorResponse(msg="存在同名的表名,请更改后再试") params['file_name_old'] = class_name serializer = self.get_serializer(data=params, request=request) serializer.is_valid(raise_exception=True) self.perform_create(serializer) return DetailResponse(data=serializer.data, msg="新增成功") def previewCode(self,request): id = get_parameter_dic(request).get('id',None) instance = self.filter_queryset(self.get_queryset()).filter(id=id).first() serializer = self.get_serializer(instance) data = GenerateCode().generate(serializer.data) return SuccessResponse(data=data,total=len(data)) def generateMount(self,request): id = get_parameter_dic(request).get('id',None) isReload = get_parameter_dic(request).get('isReload',False) instance = self.filter_queryset(self.get_queryset()).filter(id=id).first() if not instance: return ErrorResponse(msg="id error") serializer = self.get_serializer(instance) object = serializer.data # vue的route name VueIndexName = 'lyAutoCode%s' % object['class_name'] try: # 在事务开始前创建保存点 save_id = transaction.savepoint() # 以下代码会在事务中执行 # 配置路由菜单 parent_menu = object['parent_menu'] if object['parent_menu'] else None if instance.menu: menu_instance = instance.menu Menu.objects.filter(id=menu_instance.id).update(name=object['verbose_name'], web_path=VueIndexName,sort=object['menu_sort'],parent_id=parent_menu) else: menu_instance,created = Menu.objects.get_or_create(name=object['verbose_name'], sort=object['menu_sort'],web_path=VueIndexName, isautopm=1) if parent_menu: menu_instance.parent_id = parent_menu menu_instance.save() instance.menu = menu_instance instance.save() data = GenerateCode().generate(object, True, menu_instance) if not data: # 回滚到保存点 transaction.savepoint_rollback(save_id) return ErrorResponse(msg="生成文件错误") instance.file_name_old = object['class_name'] instance.is_mount = True instance.save() # 提交从保存点到当前状态的所有数据库事务操作 transaction.savepoint_commit(save_id) if isReload: restart_with_reloader() return DetailResponse(msg="操作成功") except Exception as e: # 回滚到保存点 transaction.savepoint_rollback(save_id) # 处理代码 raise e def syncdb(self,request): result = GenerateCode().syncdb() if result: return DetailResponse(msg="数据库同步成功") return ErrorResponse(msg="数据库同步失败,请查看后端IDE报错内容,或重启后端项目重试同步")