@@ -686,7 +686,17 @@ def validate(self, attrs):
686686 pro_id_list = app_now .values_list ("product_id" , flat = True ).distinct ()
687687 # 验证 product 的依赖项均已包含
688688 pro_queryset = ProductHub .objects .filter (id__in = pro_id_list )
689+ app_target_all = ApplicationHub .objects .filter (
690+ product_id__in = pro_id_list )
691+ # 考虑到同产品下会有同名服务情况,做去重处理,按照时间版本号取最新
692+ app_target = []
689693 for pro in pro_queryset :
694+ for ser in json .loads (pro .pro_services ):
695+ app_target .append (
696+ app_target_all .filter (
697+ app_name = ser ["name" ], app_version = ser ["version" ]
698+ ).last ()
699+ )
690700 # 无依赖项则跳过
691701 if not pro .pro_dependence :
692702 continue
@@ -711,26 +721,6 @@ def validate(self, attrs):
711721 app_target_all = ApplicationHub .objects .filter (
712722 product_id__in = pro_id_list )
713723
714- # 考虑到同产品下会有同名服务情况,做去重处理,按照时间版本号取最新
715- app_target_id_ls = []
716- for pro_id in pro_id_list :
717- # 同产品的 app_name 集合
718- app_name_set = set ()
719- app_ls = app_target_all .filter (product_id = pro_id )
720- for app in app_ls :
721- if app .app_name not in app_name_set :
722- new_version = app_ls .filter (
723- app_name = app .app_name
724- ).order_by ("-created" ).first ().app_version
725- if new_version == app .app_version :
726- app_name_set .add (app .app_name )
727- app_target_id_ls .append (app .id )
728-
729- # 获取目标 app
730- app_target = app_target_all .filter (
731- id__in = app_target_id_ls , is_release = True
732- )
733-
734724 # 所有 affinity 为 tengine 字段 (Web 服务),不参与比较
735725 now_set = set (filter (
736726 lambda x : x .extend_fields .get ("affinity" ) != "tengine" , app_now ))
@@ -899,6 +889,81 @@ class Meta:
899889 "module" , "module_id" )
900890
901891
892+ class ProductCompositionSerializer (ModelSerializer ):
893+ pro_ser_others = serializers .SerializerMethodField ()
894+ pro_services = serializers .CharField (
895+ # child=serializers.DictField(),
896+ help_text = "产品包含服务列表" ,
897+ required = True ,
898+ error_messages = {"required" : "必须包含[pro_services]字段" }
899+ )
900+ pro_name = serializers .CharField (help_text = "产品名称" , required = True ,
901+ error_messages = {"required" : "请填写产品名称" })
902+ pro_version = serializers .CharField (help_text = "产品版本" , required = True ,
903+ error_messages = {"required" : "请填写产品版本" })
904+
905+ def get_pro_ser_others (self , obj , ** kwargs ):
906+ res_list = []
907+ all_apps_set , all_true_apps_set = set (), set ()
908+ if obj .applicationhub_set .exists ():
909+ all_apps = obj .applicationhub_set .values_list ("app_name" , "app_version" )
910+ for app in all_apps :
911+ all_apps_set .add ("," .join (app ))
912+ pro_ser = kwargs .get ('pro_ser' )
913+ pro_services = pro_ser if pro_ser else json .loads (obj .pro_services )
914+ for t_app in pro_services :
915+ all_true_apps_set .add (f"{ t_app ['name' ]} ,{ t_app ['version' ]} " )
916+ # 一部分用作校验用
917+ if pro_ser :
918+ return all_true_apps_set - all_apps_set
919+
920+ for r_app in all_apps_set - all_true_apps_set :
921+ r_app_ls = r_app .split ("," )
922+ res_list .append (
923+ {
924+ "name" : r_app_ls [0 ],
925+ "version" : r_app_ls [1 ],
926+ }
927+ )
928+ return res_list
929+
930+ def validate_pro_services (self , pro_services ):
931+ pro_services = json .loads (pro_services )
932+ if not isinstance (pro_services , list ):
933+ raise ValidationError ({
934+ "pro_services" : "pro_services必须是list"
935+ })
936+ pro_ser_len = len (pro_services )
937+ ser_name = {}
938+ for app in pro_services :
939+ ser_name [app .get ('name' , "" )] = app .get ('version' , '' )
940+ if len (ser_name ) != pro_ser_len :
941+ raise ValidationError ({
942+ "pro_services" : "产品内服务名称需保证唯一或字段传递异常"
943+ })
944+ return pro_services
945+
946+ def validate (self , attrs ):
947+ pro_name = attrs .get ("pro_name" )
948+ pro_version = attrs .get ("pro_version" )
949+ pro_obj = ProductHub .objects .filter (pro_name = pro_name , pro_version = pro_version ).first ()
950+ if not pro_obj :
951+ raise ValidationError ({
952+ "pro_services" : "请填写正确的产品名称和版本"
953+ })
954+
955+ diff_ser = self .get_pro_ser_others (pro_obj , pro_ser = attrs .get ("pro_services" ))
956+ if diff_ser :
957+ raise ValidationError ({
958+ "pro_services" : f"存在不归属于当前产品的服务{ diff_ser } "
959+ })
960+ return attrs
961+
962+ class Meta :
963+ model = ProductHub
964+ fields = ("pro_name" , "pro_version" , "pro_services" , "pro_ser_others" )
965+
966+
902967class DeleteComponentSerializer (ModelSerializer ):
903968 """
904969 基础组件序列化
0 commit comments