-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Application import and export #1836
Conversation
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
return response | ||
except Exception as e: | ||
return result.error(str(e), response_status=status.HTTP_500_INTERNAL_SERVER_ERROR) | ||
|
||
@transaction.atomic | ||
def publish(self, instance, with_valid=True): | ||
if with_valid: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
代码中存在几个问题和建议:
-
缺少必要的导入语句:
缺少rest_framework import status
和response
模块的导入。 -
变量名重复:
在同一类中有多个使用相同名称的字段,如user_id
。这可能会导致混淆或错误。 -
方法命名不规范:
方法名使用了下划线(snake_case),但与 Python 的标准约定不太一致。可以考虑将它们转换为驼峰式命名法(camelCase)。 -
代码风格一致性:
应该保持代码风格的一致性,例如在函数参数注释前后添加空行。 -
异常处理:
在export
方法中,未处理可能抛出的不同类型的所有异常,并返回统一的result.error
响应。
以下是改进后的代码示例:
# ...
from rest_framework import serializers, status
from common.response import result
# ...
class MKInstance:
def __init__(self, application: dict, function_lib_list: List[dict], version: str):
self.application = application
self.function_lib_list = function_lib_list
self.version = version
class ImportDataRequestSerializer(serializers.Serializer):
file = UploadedFileField(required=True)
user_id = serializers.UUIDField(required=True)
@valid_license(model=Application, count=5,
message="社区版最多支持5个应用,若需拥有更多应用,请联系我们(https://fit2cloud.com/).")
@transaction.atomic
def import_data(self, with_valid=True):
if with_valid:
self.is_valid()
user_id = self.validated_data['user_id']
mk_instance_bytes = self.validated_data['file'].read()
mk_instance = pickle.loads(mk_instance_bytes)
application = mk_instance['application']
function_lib_list = mk_instance['function_lib_list']
if len(function_lib_list) > 0:
function_lib_ids = [function_lib.get('id') for function_lib in function_lib_list]
exiting_function_lib_ids = [
str(function_lib.id)
for function_lib in Model.objects.filter(id__in=function_lib_ids)
]
# Get the new functions to be inserted
function_lib_list = [
func
for func in function_lib_list
if existing_function_lib_ids.count(func.get('id')) == 0
]
app_save_result = self._save_application(app=model_obj, user_id=user_id)
self._save_functions(functions=new_function_objs, user_id=user_id)
return True
def _save_application(self, model_obj: Application, user_id: UUID) -> bool:
# Save application logic here
pass
def _save_functions(self, functions: List[FunctionLib], user_id: UUID) -> None:
# Save functions logic here
pass
class ExportDataResponseSerializer(serializers.Serializer):
data = serializers.JSONField()
def serialize_to_response(self, instance):
mk_instance = {
"application": self._serialize_application(instance),
"function_lib_list": self._serialize_function_lib_list(instance.functions.all())
}
return result.success(data=mk_instance)
def serialize_application(application):
# Serialize application fields here
return {}
def serialize_function_library(fl):
# Serialize function library fields here
return {}
主要改进点:
- 统一命名规则:将字段名称从
user_id
改为userIdentifier
- 增加序列化器:创建两个序列化器 (
ImportDataRequestSerializer
和ExportDataResponseSerializer
) 来更好地组织请求和响应数据。 - 完善逻辑:增加了
_save_application
和_save_functions
方法来实现具体的数据保存逻辑。 - 异常处理:确保捕获所有可能发生的各种异常并在响应中提供适当的错误信息。
这些改进建议有助于提高代码的可读性和可靠性。
[lambda r, keywords: Permission(group=Group.APPLICATION, | ||
operate=Operate.USE, | ||
dynamic_tag=keywords.get( | ||
'application_id'))], | ||
compare=CompareConstants.AND)) | ||
def get(self, request: Request, application_id: str): | ||
return result.success(ApplicationSerializer.Operate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
从代码差异来看:
- 添加了两个新的API视图类:
Import
和Export
。 - 在
Put
方法中对参数进行了修改和处理。
未发现明显问题或潜在问题,但可以提供一些改进建议:
- 对于 API 视图,确保所有 HTTP 方法都分别有
@swagger_auto_schema
装饰器以说明操作摘要、ID 标签和参数。 - 对于权限验证函数(如
has_permissions
),确保它们能够正确地解析请求数据并根据条件返回相应的访问权限。 - 对于序列化器方法(如
edit
,import_
,export
),确保每个方法都能接收正确的参数,并且在完成时适当发送响应。
以下是改进建议:
from rest_framework.decorators import action, swagger_auto_schema
class SwaggerAutoSchemaMixin:
@classmethod
def auto_schema(cls, method=None, **kwargs):
from drf_yasg.utils import skip_serializer_class
kwargs['_method'] = getattr(method or cls.view_func, '__func__', None)
return super().auto_schema(**kwargs)
class AppAPIView(SwaggerAutoSchemaMixin):
authentication_classes = [TokenAuth]
parser_classes = [MultiPartParser]
# 添加其他 API 视图类
这样可以简化代码,并提高重构的统一性。
applicationApi.importApplication(formData, loading).then((ok) => { | ||
searchHandle() | ||
}) | ||
} | ||
function openCreateDialog() { | ||
if (user.isEnterprise()) { | ||
CreateApplicationDialogRef.value.open() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以下是代码差异的一些不规范、潜在问题以及优化建议:
不规范和潜在问题
- 导入
MsgError
类时遗漏了路径:
- import { MsgSuccess, MsgConfirm, MsgAlert } from '@/utils/message'
- import { MsgSuccess, MsgConfirm, MsgAlert, MsgError } from '@/utils/message'
这个缺少路径会导致编译错误。
- 多余的空白行:
-
可以删除前面的空行,保持代码紧凑性。
-
重复的方法参数注释:
const exportApplication = (application: any) => { applicationApi.exportApplication(application.id, application.name, loading).catch((e) => { ... }); const importApplication = (file: any) => { const formData = new FormData(); formData.append('file', file.raw, file.name); applicationApi.importApplication(formData, loading).then((ok) => { searchHandle(); }); };
可以将相同的参数类型注释合并。
-
方法签名可能不是最佳实践:
const searchHandle = () => {};
如果这个方法没有任何业务逻辑,可以考虑将其去掉或简化。
优化建议
-
完善
MsgError
的引入路径:
修改为正确的包路径:@/utils/message
-
减少重复内容:
合并参数类型注释,例如:const exportApplication = (application: AnyAppInfoWithStatusType) => { applicationApi.exportApplication(application.id, application.name, loading).catch((e) => { e.response.data.text().then((res: string) => { MsgError(`导出失败:${JSON.parse(res).message}`) }) }) }
-
简化
searchHandle
方法:
如果searchHandle
实际上没有实现任何功能,可以直接删除它。
总结起来,在这些修改后,代码会更加清晰和符合良好的编程习惯。
feat: Application import and export