Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • arkindex/backend
1 result
Show changes
Commits on Source (4)
# Generated by Django 4.1.7 on 2024-03-28 14:54
from django.db import migrations, models
def update_unique_elements(apps, schema_editor):
"""Update unique_elements to False when some elements are already duplicated"""
Dataset = apps.get_model("training", "Dataset")
DatasetElement = apps.get_model("training", "DatasetElement")
Dataset.objects.filter(
models.Exists(
DatasetElement.objects
.filter(set__dataset_id=models.OuterRef("pk"))
.values("element")
.annotate(dups=models.Count("element"))
.filter(dups__gte=2)
)
).update(unique_elements=False)
class Migration(migrations.Migration):
dependencies = [
("training", "0007_datasetset_model"),
]
operations = [
migrations.AddField(
model_name="dataset",
name="unique_elements",
field=models.BooleanField(default=True),
),
migrations.RunPython(
update_unique_elements,
reverse_code=migrations.RunPython.noop,
elidable=True,
),
]
...@@ -266,6 +266,7 @@ class Dataset(models.Model): ...@@ -266,6 +266,7 @@ class Dataset(models.Model):
name = models.CharField(max_length=100, validators=[MinLengthValidator(1)]) name = models.CharField(max_length=100, validators=[MinLengthValidator(1)])
description = models.TextField(validators=[MinLengthValidator(1)]) description = models.TextField(validators=[MinLengthValidator(1)])
state = EnumField(DatasetState, default=DatasetState.Open, max_length=50) state = EnumField(DatasetState, default=DatasetState.Open, max_length=50)
unique_elements = models.BooleanField(default=True)
class Meta: class Meta:
constraints = [ constraints = [
......
...@@ -4,7 +4,7 @@ from collections import defaultdict ...@@ -4,7 +4,7 @@ from collections import defaultdict
from textwrap import dedent from textwrap import dedent
from django.db import transaction from django.db import transaction
from django.db.models import Count, Q from django.db.models import Count, Exists, OuterRef, Q
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from rest_framework import permissions, serializers from rest_framework import permissions, serializers
from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.exceptions import PermissionDenied, ValidationError
...@@ -575,6 +575,17 @@ class DatasetSerializer(serializers.ModelSerializer): ...@@ -575,6 +575,17 @@ class DatasetSerializer(serializers.ModelSerializer):
raise ValidationError("Either do not specify set names to use the default values, or specify a non-empty list of names.") raise ValidationError("Either do not specify set names to use the default values, or specify a non-empty list of names.")
return set_names return set_names
def validate_unique_elements(self, unique):
if unique is True and self.instance and Exists(
DatasetElement.objects
.filter(set__dataset_id=OuterRef(self.instance.pk))
.values("element")
.annotate(dups=Count("element"))
.filter(dups__gte=2)
):
raise ValidationError("Elements are currently contained by multiple sets.")
return unique
def validate(self, data): def validate(self, data):
data = super().validate(data) data = super().validate(data)
...@@ -636,6 +647,7 @@ class DatasetSerializer(serializers.ModelSerializer): ...@@ -636,6 +647,7 @@ class DatasetSerializer(serializers.ModelSerializer):
# Hidden field to set the creator as the authenticated user # Hidden field to set the creator as the authenticated user
"default_creator", "default_creator",
"task_id", "task_id",
"unique_elements",
"created", "created",
"updated", "updated",
) )
...@@ -702,7 +714,18 @@ class DatasetElementSerializer(serializers.ModelSerializer): ...@@ -702,7 +714,18 @@ class DatasetElementSerializer(serializers.ModelSerializer):
def validate(self, data): def validate(self, data):
data = super().validate(data) data = super().validate(data)
data.pop("dataset") dataset = data.pop("dataset")
if dataset.unique_elements and (
set := (
dataset.sets
.filter(set_elements__element_id=data["element_id"])
.values_list("name", flat=True)
.first()
)
):
raise ValidationError({"element_id": [
f"The dataset prevent duplication and this element is already present in set {set}."
]})
return data return data
......