diff --git a/CHANGELOG.md b/CHANGELOG.md index 8091b53ef437..7800f0fc6bb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - TDB ### Fixed -- TDB +- \[SDK\] Ability to create attributes with blank default values + () ### Security - TDB diff --git a/cvat/apps/engine/migrations/0073_alter_attributespec_default_value_and_more.py b/cvat/apps/engine/migrations/0073_alter_attributespec_default_value_and_more.py new file mode 100644 index 000000000000..7bfe361c875b --- /dev/null +++ b/cvat/apps/engine/migrations/0073_alter_attributespec_default_value_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.1 on 2023-07-10 15:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("engine", "0072_alter_issue_updated_date"), + ] + + operations = [ + migrations.AlterField( + model_name="attributespec", + name="default_value", + field=models.CharField(blank=True, max_length=128), + ), + migrations.AlterField( + model_name="attributespec", + name="values", + field=models.CharField(blank=True, max_length=4096), + ), + ] diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index 5e9f6781eb2c..8b1ee700271f 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -881,8 +881,8 @@ class AttributeSpec(models.Model): mutable = models.BooleanField() input_type = models.CharField(max_length=16, choices=AttributeType.choices()) - default_value = models.CharField(max_length=128) - values = models.CharField(max_length=4096) + default_value = models.CharField(blank=True, max_length=128) + values = models.CharField(blank=True, max_length=4096) class Meta: default_permissions = () diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index a92df38a0a22..f3303ea0ab03 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -214,7 +214,7 @@ class Meta: class AttributeSerializer(serializers.ModelSerializer): values = serializers.ListField(allow_empty=True, - child=serializers.CharField(max_length=200), + child=serializers.CharField(allow_blank=True, max_length=200), ) class Meta: diff --git a/cvat/schema.yml b/cvat/schema.yml index 47a68af2e933..cbb4310c538e 100644 --- a/cvat/schema.yml +++ b/cvat/schema.yml @@ -5993,7 +5993,6 @@ components: type: string maxLength: 200 required: - - default_value - input_type - mutable - name @@ -6011,16 +6010,13 @@ components: $ref: '#/components/schemas/InputTypeEnum' default_value: type: string - minLength: 1 maxLength: 128 values: type: array items: type: string - minLength: 1 maxLength: 200 required: - - default_value - input_type - mutable - name diff --git a/tests/python/sdk/test_projects.py b/tests/python/sdk/test_projects.py index 74ecf5e69084..852a286fc288 100644 --- a/tests/python/sdk/test_projects.py +++ b/tests/python/sdk/test_projects.py @@ -115,6 +115,30 @@ def test_can_create_empty_project(self): assert project.id != 0 assert project.name == "test project" + def test_can_create_project_with_attribute_with_blank_default(self): + project = self.client.projects.create( + spec=models.ProjectWriteRequest( + name="test project", + labels=[ + models.PatchedLabelRequest( + name="text", + attributes=[ + models.AttributeRequest( + name="text", + mutable=True, + input_type=models.InputTypeEnum("text"), + values=[], + default_value="", + ) + ], + ) + ], + ) + ) + + labels = project.get_labels() + assert labels[0].attributes[0].default_value == "" + def test_can_create_project_from_dataset(self, fxt_coco_dataset: Path): pbar_out = io.StringIO() pbar = make_pbar(file=pbar_out)