Skip to content
Snippets Groups Projects
Commit 7c1d28b2 authored by Valentin Rigal's avatar Valentin Rigal
Browse files

CreateClassification

parent c5fa6103
No related branches found
No related tags found
No related merge requests found
......@@ -377,7 +377,7 @@ class ClassificationCreate(CreateAPIView):
}
def perform_create(self, serializer):
if serializer.validated_data['source'] and serializer.validated_data['source'].slug == 'manual':
if serializer.validated_data['worker_version'] is None:
# A manual classification is immediately valid
serializer.save(
moderator=self.request.user,
......
......@@ -113,21 +113,20 @@ class ClassificationCreateSerializer(serializers.ModelSerializer):
"""
Serializer to create a single classification, defaulting to manual
"""
source = DataSourceSlugField(tool_type=MLToolType.Classifier, default=None)
worker_version = serializers.PrimaryKeyRelatedField(queryset=WorkerVersion.objects.all(), default=None)
confidence = serializers.FloatField(
min_value=0,
max_value=1,
required=False,
help_text='Confidence score for this classification. Required for non-manual sources.'
'Will be ignored and set to 1.0 for classifications on a `manual` source.',
help_text='Confidence score for this classification. Required for classifications with a worker version.'
'Will be ignored and set to 1.0 for a `manual` classification.',
)
# Use a NullBooleanField here to make it default to None and check later on non-manual sources
# Use a NullBooleanField here to make it default to None and check later on non-manual classifications
high_confidence = serializers.NullBooleanField(
required=False,
help_text='Whether or not a machine learning tool marks this as the correct classification. '
'Required for non-manual sources. '
'Will be ignored and set to True for classifications on a `manual` source.',
'Required for classifications with a worker version. '
'Will be ignored and set to True for `manual` classifications.',
)
state = EnumField(ClassificationState, read_only=True)
......@@ -137,7 +136,6 @@ class ClassificationCreateSerializer(serializers.ModelSerializer):
'id',
'element',
'ml_class',
'source',
'worker_version',
'confidence',
'high_confidence',
......@@ -145,10 +143,6 @@ class ClassificationCreateSerializer(serializers.ModelSerializer):
)
read_only_fields = ('id', 'state')
validators = [
UniqueTogetherValidator(
queryset=Classification.objects.filter(worker_version_id__isnull=True),
fields=['element', 'source', 'ml_class']
),
UniqueTogetherValidator(
queryset=Classification.objects.filter(source_id__isnull=True),
fields=['element', 'worker_version', 'ml_class']
......@@ -166,43 +160,26 @@ class ClassificationCreateSerializer(serializers.ModelSerializer):
corpus__in=Corpus.objects.writable(self.context['request'].user))
def validate(self, data):
# Do not check data for manual classifications
# Note that (source, class, element) unicity is already checked by DRF
# Note that (worker_version, class, element) unicity is already checked by DRF
errors = {}
user = self.context['request'].user
source = data.get('source')
worker_version = data.get('worker_version')
if not source and not worker_version:
raise ValidationError({
'source': ['This field XOR worker_version field must be set to create a classification'],
'worker_version': ['This field XOR source field must be set to create a classification']
})
elif source and worker_version:
raise ValidationError({
'source': ['You can only refer to a DataSource XOR a WorkerVersion on a classification'],
'worker_version': ['You can only refer to a DataSource XOR a WorkerVersion on a classification']
})
elif source:
slug = data.get('source').slug
if slug == 'manual':
return data
if not user or not user.is_internal:
errors['source'] = [
'An internal user is required to create a classification with '
f'the non-manual source "{slug}"'
]
elif worker_version and (not user or not user.is_internal):
errors['worker_version'] = [
'An internal user is required to create a classification with '
f'the worker_version "{worker_version.id}"'
]
# Additional validation for transcriptions with an internal source
# Do not check data for manual classifications
if worker_version is None:
return data
# Additional validation for transcriptions with a worker version
version_required_error = 'is required to create a classification with a worker version.'
if not user or not user.is_internal:
errors['worker_version'] = [f'An internal user {version_required_error}']
if data.get('confidence') is None:
errors['confidence'] = ['This field is required for non manual sources.']
errors['confidence'] = [f'This field {version_required_error}']
if data.get('high_confidence') is None:
errors['high_confidence'] = ['This field is required for non manual sources.']
errors['high_confidence'] = [f'This field {version_required_error}']
if errors:
raise ValidationError(errors)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment