-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: implement Tool model and related API for Tool management #2908
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.contrib import admin | ||
|
||
# Register your models here. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# coding=utf-8 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# coding=utf-8 | ||
|
||
from common.mixins.api_mixin import APIMixin | ||
from common.result import ResultSerializer | ||
from tools.serializers.tool import ToolModelSerializer, ToolCreateRequest | ||
|
||
|
||
class ToolCreateResponse(ResultSerializer): | ||
def get_data(self): | ||
return ToolModelSerializer() | ||
|
||
|
||
class ToolCreateAPI(APIMixin): | ||
@staticmethod | ||
def get_request(): | ||
return ToolCreateRequest | ||
|
||
@staticmethod | ||
def get_response(): | ||
return ToolCreateResponse |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class ToolConfig(AppConfig): | ||
default_auto_field = 'django.db.models.BigAutoField' | ||
name = 'tools' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Generated by Django 5.2 on 2025-04-17 06:03 | ||
|
||
import django.db.models.deletion | ||
import uuid_utils.compat | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('users', '0001_initial'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Tool', | ||
fields=[ | ||
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), | ||
('name', models.CharField(max_length=64, verbose_name='函数名称')), | ||
('desc', models.CharField(max_length=128, verbose_name='描述')), | ||
('code', models.CharField(max_length=102400, verbose_name='python代码')), | ||
('input_field_list', models.JSONField(default=list, verbose_name='输入字段列表')), | ||
('init_field_list', models.JSONField(default=list, verbose_name='启动字段列表')), | ||
('icon', models.CharField(default='/ui/favicon.ico', max_length=256, verbose_name='函数库icon')), | ||
('is_active', models.BooleanField(default=True)), | ||
('scope', models.CharField(choices=[('SHARED', '共享'), ('WORKSPACE', '工作空间可用')], default='WORKSPACE', max_length=20, verbose_name='可用范围')), | ||
('tool_type', models.CharField(choices=[('INTERNAL', '内置'), ('PUBLIC', '公开')], default='PUBLIC', max_length=20, verbose_name='函数类型')), | ||
('template_id', models.UUIDField(default=None, null=True, verbose_name='模版id')), | ||
('module_id', models.CharField(default='root', max_length=64, null=True, verbose_name='模块id')), | ||
('init_params', models.CharField(max_length=102400, null=True, verbose_name='初始化参数')), | ||
('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')), | ||
('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.user', verbose_name='用户id')), | ||
], | ||
options={ | ||
'db_table': 'tool', | ||
}, | ||
), | ||
] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided code looks mostly correct and follows best practices for a Django migration file. Here are some minor points of review:
Overall, the migration script should work fine, but keep these considerations in mind. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided Django migration code has some small issues that can be addressed for better readability and maintainability:
Here is the revised version with these improvements: # Generated by Django
import django.contrib.postgres.fields
import django.db.models.deletion
import uuid_utils.compat
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Tool',
fields=[
# Unique identifier for the tool
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='Unique ID')),
# Name of the function/algorithm
('name', models.CharField(max_length=64, verbose_name='Function Name')),
# Description of the algorithm/function
('desc', models.CharField(max_length=128, verbose_name='Description')),
# Python code implementing the algorithm/function
('code', models.CharField(max_length=102400, verbose_name='Python Code')),
# List of input parameters' descriptions formatted as JSON
('input_field_list', models.JSONField(default=dict, verbose_name='Input Field List')),
# List of initialization parameters' values formatted as JSON
('init_field_list', models.JSONField(default=list, verbose_name='Init Field List')),
# URL or path to the icon representing the function/library
('icon', models.CharField(default='/ui/favicon.ico', max_length=256, verbose_name='Icon URL')),
# Indicates if the tool is active or not
('is_active', models.BooleanField(default=True)),
# Permission type for access to the tool
('permission_type', models.CharField(
choices=[('SHARED', 'Shared'), ('PRIVATE', 'Private')],
default='PRIVATE',
max_length=20,
verbose_name='Permission Type'
)),
# Type of function/tool (built-in vs. open)
('tool_type', models.CharField(
choices=[('INTERNAL', 'Internal'), ('PUBLIC', 'Public')],
default='PUBLIC',
max_length=20,
verbose_name='Tool Type'
)),
# UUID of the template associated with the tool
('template_id', models.UUIDField(null=True, verbose_name='Template ID')),
# UUID of the module containing the tool
('module_id', models.UUIDField(default='root', null=True, verbose_name='Module ID')),
# Additional parameters used for initializing the function
('init_params', models.CharField(max_length=102400, null=True, verbose_name='Init Parameters')),
# Timestamp when the tool was created
('create_time', models.DateTimeField(auto_now_add=True, null=True)),
# Timestamp when the tool was last updated
('update_time', models.DateTimeField(auto_now=True, null=True)),
# User who owns the tool
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tools', to='users.User', verbose_name='User ID')),
],
options={
'db_table': 'tool',
},
),
] These changes ensure that the migration script is clean, readable, and adheres to typical naming conventions and best practices in Django development. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code looks generally well-formed and follows best practices for a Django migration file. However, there are a few recommendations that can improve it:
Here is the revised version: # Generated by Django 5.2 on 2025-04-16 09:49
from django.contrib.postgres.fields import ArrayField, JSONField
import django.db.models.deletion
from django.utils.translation import gettext_lazy as _
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Tool',
fields=[
('id', models.PositiveBigIntegerField(primary_key=True, auto_increment=True)),
('name', models.CharField(max_length=64, verbose_name=_('Function Name'))),
('desc', models.CharField(max_length=128, verbose_name=_('Description'))),
('code', models.TextField(verbose_name=_('Python Code'))),
(
'input_field_list',
ArrayField(models.JSONField(default=dict,), blank=False, null=True,
verbose_name=_('Input Field List')),
),
("init_field_list", JSONField(blank=False, null=True, verbose_name=_('Initialization Fields'))),
('icon', models.URLField(default='/ui/favicon.ico', max_length=256, verbose_name=_('Icon URL'))),
('is_active', models.BooleanField(default=True, verbose_name=_('Active'))),
(
"permission_type",
models.CharField(
choices=[
(_('Shared'), _('Shared')),
(_('Private'), _('Private'))
],
default=_('Private'),
max_length=20,
verbose_name=_('Permission Type')
)
),
(
'tool_type',
models.CharField(
choices=[
(_('Internal'), _('Internal')),
(_('Public'), _('Public'))
],
default=_('Public'),
max_length=20,
verbose_name=_('Tool Type')
),
),
('template_id', models.UUIDField(unique=False, nullable=True, verbose_name=_('Template ID')),
),
('module_id', models.CharField(default='root', help_text=('Root module path')), max_length=256, nullable=True)
verbose_name=_('Module Path')),
('initial_params', models.TextField(blank=True, null=True, verbose_name=_('Initial Parameters'))),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name=_('Creation Time')),
blank=True, null=True),
('update_time', models.DateTimeField(auto_now=True, verbose_name=_('Update Time')),
blank=True, null=True),
('creator', models.ForeignKey(null=True, on_delete=models.SET_NULL, related_name="created_tool",
related_query_name="_tool",
verbose_name=_('Creator'))),
('editor', models.ForeignKey(null=True, on_delete=models.SET_NULL, related_name="edited_tool",
related_query_name="_tool",
verbose_name=_('Editor'))),
('owner', models.UUIDField(default='', max_length=36, verbose_name=_('Owner GUID')))
],
options={
'abstract': False,
},
),
] Note that I've also added fields for creator, editor, and owner based on common requirements in such applications. Adjust according to actual needs. Additionally, I used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The migration looks well-structured but has a couple of minor improvements that can be made:
Here's the revised migration: @@ -0,0 +1,44 @@
+# Generated by Django 5.2 on 2025-04-16 09:49
+
+import django.contrib.postgres.fields
+import django.db.models.deletion
+import uuid_utils.compat
+from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Tool',
fields=[
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')),
('name', models.CharField(max_length=64, verbose_name='函数名称',
help_text="Function's name")),
('desc', models.CharField(max_length=128, verbose_name='描述',
help_text="Description")),
('code', models.TextField(verbose_name='Python代码',
help_text="Code in Python format")),
('input_field_list', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=64), default=list, size=None, verbose_name='输入字段列表')),
('init_field_list', models.JSONField(default=list, verbose_name='启动字段列表')),
('icon', models.URLField(default='/ui/favicon.ico', max_length=256,
verify_exists=True, help_text="URL for the function library icon")),
('is_active', models.BooleanField(default=True, verbose_name='是否启用',
db_index=True)),
('permission_type', models.CharField(choices=[('SHARED', '共享'), ('PRIVATE', '私有')], default='PRIVATE', max_length=20, verbose_name='权限类型')),
('tool_type', models.CharField(choices=[('INTERNAL', '内置'), ('PUBLIC', '公开')], default='PUBLIC', max_length=20, verbose_name='函数类型')),
('template_id', models.UUIDField(default=None, null=True, blank=True, verbose_name='模板id')),
('module_id', models.CharField(default=None, max_length=64, null=True, blank=True, help_text="Module ID", db_index=True)), # Added 'blank=True' here
('init_params', models.TextField(null=True, blank=True, verbose_name=('初始化参数'))),
('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tools', to='users.User', verbose_name='用户id')),
],
options={
'db_table': 'tool',
},
),
] Key Changes:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided migration code for creating the
Here's an improved version of your migration file with these corrections: @@ -0,0 +1,40 @@
+# Generated by Django 5.2 on 2025-04-17 06:03
+import django.db.models.deletion
+import uuid_utils.compat
+from django.db import migrations, models
+class Migration(migrations.Migration):
+ initial = True
+ dependencies = [
+ ('users', '0001_initial'),
+ ]
+ operations = [
+ migrations.CreateModel(
+ name='Tool',
+ fields=[
+ ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键ID')),
+ ('name', models.CharField(max_length=64, verbose_name='函数名称')),
+ ('desc', models.CharField(max_length=128, verbose_name='描述')),
+ ('code', models.CharField(max_length=102400, verbose_name='Python代码')),
+ ('input_field_list', models.JSONField(default=list, verbose_name='输入字段列表')),
+ ('init_field_list', models.JSONField(default=list, verbose_name='启动字段列表')),
+ ('icon', models.CharField(default='/ui/favicon.ico', max_length=256, verbose_name='函数库图标')),
+ ('is_active', models.BooleanField(default=True)),
+ ('scope', models.CharField(choices=[('SHARED', '共享'), ('WORKSPACE', '工作空间可用')], default='WORKSPACE', max_length=20, verbose_name='可用范围')),
+ ('tool_type', models.CharField(choices=[('INTERNAL', '内置'), ('PUBLIC', '公开')], default='PUBLIC', max_length=20, verbose_name='函数类型')),
+ ('template_id', models.UUIDField(null=True, verbose_name='模板ID')),
+ ('module_id', models.CharField(default='root', max_length=64, null=True, verbose_name='模块ID')),
+ ('init_params', models.CharField(max_length=102400, null=True, verbose_name='初始化参数')),
+ ('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
+ ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.User', verbose_name='用户ID')),
+ ],
+ options={
+ 'db_table': 'tool',
+ },
+ ),
+ ] Optimization Suggestions:
These changes will make your migration more robust and potentially faster. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .tool import * |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import uuid_utils.compat as uuid | ||
from django.db import models | ||
|
||
from users.models import User | ||
|
||
|
||
class ToolScope(models.TextChoices): | ||
SHARED = "SHARED", '共享' | ||
WORKSPACE = "WORKSPACE", "工作空间可用" | ||
|
||
|
||
class ToolType(models.TextChoices): | ||
INTERNAL = "INTERNAL", '内置' | ||
PUBLIC = "PUBLIC", "公开" | ||
|
||
|
||
class Tool(models.Model): | ||
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") | ||
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id") | ||
name = models.CharField(max_length=64, verbose_name="函数名称") | ||
desc = models.CharField(max_length=128, verbose_name="描述") | ||
code = models.CharField(max_length=102400, verbose_name="python代码") | ||
input_field_list = models.JSONField(verbose_name="输入字段列表", default=list) | ||
init_field_list = models.JSONField(verbose_name="启动字段列表", default=list) | ||
icon = models.CharField(max_length=256, verbose_name="函数库icon", default="/ui/favicon.ico") | ||
is_active = models.BooleanField(default=True) | ||
scope = models.CharField(max_length=20, verbose_name='可用范围', choices=ToolScope.choices, | ||
default=ToolScope.WORKSPACE) | ||
tool_type = models.CharField(max_length=20, verbose_name='函数类型', choices=ToolType.choices, | ||
default=ToolType.PUBLIC) | ||
template_id = models.UUIDField(max_length=128, verbose_name="模版id", null=True, default=None) | ||
module_id = models.CharField(max_length=64, verbose_name="模块id", null=True, default='root') | ||
init_params = models.CharField(max_length=102400, verbose_name="初始化参数", null=True) | ||
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True) | ||
update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True, null=True) | ||
|
||
class Meta: | ||
db_table = "tool" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code provided is mostly correct and follows common Django conventions. However, there are a few points that can be improved:
Here's the updated code without the unnecessary import statement: from django.contrib.postgres.fields import ArrayField
from django.db import models
from users.models import User
class PermissionType(models.TextChoices):
SHARED = "SHARED", '共享'
PRIVATE = "PRIVATE", "私有"
class ToolType(models.TextChoices):
INTERNAL = "INTERNAL", '内置'
PUBLIC = "PUBLIC", "公开"
class Tool(models.Model):
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id")
name = models.CharField(max_length=64, verbose_name="函数名称")
desc = models.CharField(max_length=128, verbose_name="描述")
code = models.CharField(max_length=102400, verbose_name="python代码")
input_field_list = ArrayField(
verbose_name="输入字段列表",
base_field=models.JSONField(verbose_name="输入字段", default=dict)
)
init_field_list = models.JSONField(verbose_name="启动字段列表", default=list)
icon = models.CharField(max_length=256, verbose_name="函数库icon", default="/ui/favicon.ico")
is_active = models.BooleanField(default=True)
permission_type = models.CharField(max_length=20, verbose_name='权限类型', choices=PermissionType.choices, default=PermissionType.PRIVATE)
tool_type = models.CharField(max_length=20, verbose_name='函数类型', choices=ToolType.choices, default=ToolType.PUBLIC)
template_id = models.UUIDField(max_length=128, verbose_name="模版id", null=True, default=None)
module_id = models.UUIDField(max_length=128, verbose_name="模块id", null=True, default=None) # Updated indentation
init_params = models.CharField(max_length=102400, verbose_name="初始化参数", null=True, default=None) #
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True)
update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True, null=True)
class Meta:
db_table = "tool" # Removed extra space at the beginning and end These changes ensure better consistency and clarity in the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code looks generally well-structured and follows Django's best practices for defining models using Improvements
Here’s an improved version of the model incorporating some of these recommendations: from django.contrib.postgres.fields import ArrayField, JSONField
from django.db import models
from users.models import User
class PermissionType(models.TextChoices):
SHARED = "SHARED", '共享'
PRIVATE = "PRIVATE", "私有"
class ToolType(models.TextChoices):
INTERNAL = "INTERNAL", '内置'
PUBLIC = "PUBLIC", "公开"
class Tool(models.Model):
# Primary Key, should ideally be a String type for better performance
id = models.CharField(primary_key=True, max_length=64)
# ForeignKey to a user model
user = models.ForeignKey(User, on_delete=models.CASCADE)
# Name of the function/library
name = models.CharField(max_length=64, blank=True) # Optional if not required every time
# Description of the tool/function library
desc = models.CharField(max_length=256, blank=True) # Optional similar to Name
# Python script/code for the function
code = models.TextField()
# List of input fields expected by the function
input_fields = ArrayField(
base_field=JSONField(),
default=list,
verbose_name="Input parameters"
)
# Initial list/setup parameters before running the function
initial_settings = JSONField(default=dict)
icon_url = models.URLField(default="/ui/favicon.ico") # Using URLField for URLs
is_active = models.BooleanField(default=True)
# Type of permission required (shared/private)
permission_type = models.CharField(
max_length=20,
choices=PermissionType.choices,
default=PermissionType.PRIVATE
)
# Type of tool/function (internal/public)
tool_type = models.CharField(
max_length=20,
choices=ToolType.choices,
default=ToolType.PUBLIC
)
# Template identifier associated with this tool
template_uuid = models.UUIDField(unique=False, null=True, default=None)
# Module identifier where the tool belongs
module_id = models.CharField(max_length=64, default='root')
# Initialization parameters (if applicable)
init_vars = JSONField(null=True, default=None)
# Timestamps for creation and last update
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "tool" These changes aim to enhance both readability and efficiency while maintaining correctness according to existing standards and conventions used within the broader ecosystem around Django applications. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review of Code SnippetSummary: The provided code snippet defines a Potential Issues:
Optimization Suggestions:
By addressing these points, the code becomes more robust, efficient, and easier to maintain. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# coding=utf-8 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# -*- coding: utf-8 -*- | ||
import re | ||
|
||
import uuid_utils.compat as uuid | ||
from django.core import validators | ||
from django.utils.translation import gettext_lazy as _ | ||
from rest_framework import serializers | ||
|
||
from tools.models import Tool, ToolScope | ||
|
||
|
||
class ToolModelSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = Tool | ||
fields = ['id', 'name', 'icon', 'desc', 'code', 'input_field_list', 'init_field_list', 'init_params', | ||
'scope', 'is_active', 'user_id', 'template_id', | ||
'create_time', 'update_time'] | ||
|
||
|
||
class ToolInputField(serializers.Serializer): | ||
name = serializers.CharField(required=True, label=_('variable name')) | ||
is_required = serializers.BooleanField(required=True, label=_('required')) | ||
type = serializers.CharField(required=True, label=_('type'), validators=[ | ||
validators.RegexValidator(regex=re.compile("^string|int|dict|array|float$"), | ||
message=_('fields only support string|int|dict|array|float'), code=500) | ||
]) | ||
source = serializers.CharField(required=True, label=_('source'), validators=[ | ||
validators.RegexValidator(regex=re.compile("^custom|reference$"), | ||
message=_('The field only supports custom|reference'), code=500) | ||
]) | ||
|
||
|
||
class ToolCreateRequest(serializers.Serializer): | ||
name = serializers.CharField(required=True, label=_('tool name')) | ||
|
||
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, | ||
label=_('tool description')) | ||
|
||
code = serializers.CharField(required=True, label=_('tool content')) | ||
|
||
input_field_list = serializers.ListField(child=ToolInputField(), required=True, label=_('input field list')) | ||
|
||
init_field_list = serializers.ListField(required=False, default=list, label=_('init field list')) | ||
|
||
is_active = serializers.BooleanField(required=False, label=_('Is active')) | ||
|
||
|
||
class ToolSerializer(serializers.Serializer): | ||
class Create(serializers.Serializer): | ||
user_id = serializers.UUIDField(required=True, label=_('user id')) | ||
|
||
def insert(self, instance, with_valid=True): | ||
if with_valid: | ||
self.is_valid(raise_exception=True) | ||
ToolCreateRequest(data=instance).is_valid(raise_exception=True) | ||
tool = Tool(id=uuid.uuid7(), | ||
name=instance.get('name'), | ||
desc=instance.get('desc'), | ||
code=instance.get('code'), | ||
user_id=self.data.get('user_id'), | ||
input_field_list=instance.get('input_field_list'), | ||
init_field_list=instance.get('init_field_list'), | ||
scope=ToolScope.WORKSPACE, | ||
is_active=False) | ||
tool.save() | ||
return ToolModelSerializer(tool).data | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are several areas that need attention to improve the provided code. Here's a detailed review: Code Snippets Review
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.test import TestCase | ||
|
||
# Create your tests here. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
app_name = "tool" | ||
urlpatterns = [ | ||
path('workspace/<str:workspace_id>/tool/create', views.ToolCreateView.as_view()), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .tool import * |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from django.utils.translation import gettext_lazy as _ | ||
from drf_spectacular.utils import extend_schema | ||
from rest_framework.request import Request | ||
from rest_framework.views import APIView | ||
|
||
from common.auth import TokenAuth | ||
from common.auth.authentication import has_permissions | ||
from common.constants.permission_constants import PermissionConstants | ||
from common.result import result | ||
from tools.api.tool import ToolCreateAPI | ||
from tools.serializers.tool import ToolSerializer | ||
|
||
|
||
class ToolCreateView(APIView): | ||
authentication_classes = [TokenAuth] | ||
|
||
@extend_schema(methods=['POST'], | ||
description=_('Create tool'), | ||
operation_id=_('Create tool'), | ||
request=ToolCreateAPI.get_request(), | ||
responses=ToolCreateAPI.get_response(), | ||
tags=[_('Tool')]) | ||
@has_permissions(PermissionConstants.TOOL_CREATE) | ||
# @log(menu='Tool', operate="Create tool", | ||
# get_operation_object=lambda r, k: r.data.get('name')) | ||
def post(self, request: Request, workspace_id: str): | ||
print(workspace_id) | ||
return result.success(ToolSerializer.Create(data={'user_id': request.user.id}).insert(request.data)) |
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.
The code appears to be correct and well-formed according to Django migration standards. Here is a brief analysis on potential areas for improvement:
UUID Version: The
default=uuid_utils.compat.uuid7
uses version 7 UUIDs, which include time-based information and randomness. If you need to change this behavior (e.g., using the default v4), it would require updating the import statement.JSON Field Size: The
input_field_list
andinit_field_list
JSON fields are set with a maximum length of 64k characters each. This might not be necessary for all use cases. You can reduce these if you expect smaller data inputs or adjust based on your application's requirements.Nullability: The
template_id
field allows NULL values, which could potentially lead to unexpected behavior during queries that rely on non-null conditions. Consider whether allowing NULLs is appropriate based on your business logic.Data Types: Ensure that all fields are appropriately typed for their intended purposes. For example, if
init_params
primarily holds strings, consider usingLongText
instead ofCharField
for larger string sizes.Here are some specific suggestions:
input_field_list
andinit_field_list
.Overall, the code structure seems solid; additional customization may depend heavily on how you will interact with and utilize this database table within your project.