Skip to content

Commit 029baef

Browse files
committed
Added annotation characteristics
1 parent 2613db5 commit 029baef

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

api/serializers.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,12 +800,44 @@ class Meta:
800800
"confidence": {"read_only": True},
801801
}
802802

803+
class AnnotationCharacteristicsSerializer(serializers.Serializer):
804+
sex = serializers.ChoiceField(choices=['male', 'female'], required=False, allow_null=True)
805+
is_blood_fed = serializers.BooleanField(required=False, default=False)
806+
is_gravid = serializers.BooleanField(required=False, default=False)
807+
808+
def to_internal_value(self, data):
809+
sex = data.pop('sex', None)
810+
is_blood_fed = data.pop('is_blood_fed', False)
811+
is_gravid = data.pop('is_gravid', False)
812+
813+
ret = {}
814+
if sex == 'male':
815+
blood_genre = 'male'
816+
elif sex == 'female':
817+
if is_gravid and is_blood_fed:
818+
blood_genre = 'fgblood'
819+
elif is_gravid:
820+
blood_genre = 'fgravid'
821+
elif is_blood_fed:
822+
blood_genre = 'fblood'
823+
else:
824+
blood_genre = 'female'
825+
else:
826+
blood_genre = 'dk'
827+
828+
ret['blood_genre'] = blood_genre
829+
return ret
830+
831+
class Meta:
832+
fields = ("sex", "is_blood_fed", "is_gravid")
833+
803834
user_hidden_obj = serializers.HiddenField(default=serializers.CurrentUserDefault())
804835

805836
user = SimpleAnnotatorUserSerializer(read_only=True)
806837
feedback = AnnotationFeedbackSerializer(source='*', required=False)
807838

808839
classification = AnnotationClassificationSerializer(source='*', required=True, allow_null=True)
840+
characteristics = AnnotationCharacteristicsSerializer(required=False, write_only=True)
809841
best_photo_uuid = serializers.UUIDField(write_only=True, required=False)
810842
best_photo = SimplePhotoSerializer(read_only=True, allow_null=True)
811843
tags = TagListSerializerField(required=False, allow_empty=True)
@@ -866,17 +898,26 @@ def validate(self, data):
866898

867899
def create(self, validated_data):
868900
is_favourite = validated_data.pop("is_favourite", False)
901+
characteristics = validated_data.pop("characteristics", {})
902+
blood_genre = characteristics.get("blood_genre", None)
869903
with transaction.atomic():
870904
instance = super().create(validated_data)
871905
if is_favourite:
872906
FavoritedReports.objects.get_or_create(
873907
user=instance.user,
874908
report=instance.report,
875909
)
910+
if blood_genre and instance.best_photo:
911+
# Update the best photo with the blood_genre
912+
instance.best_photo.blood_genre = blood_genre
913+
instance.best_photo.save()
914+
876915
return instance
877916

878917
def update(self, instance, validated_data):
879918
is_favourite = validated_data.pop("is_favourite", False)
919+
characteristics = validated_data.pop("characteristics", {})
920+
blood_genre = characteristics.get("blood_genre", None)
880921
with transaction.atomic():
881922
instance = super().update(instance, validated_data)
882923
if is_favourite:
@@ -889,6 +930,10 @@ def update(self, instance, validated_data):
889930
user=instance.user,
890931
report=instance.report,
891932
).delete()
933+
if blood_genre and instance.best_photo:
934+
# Update the best photo with the blood_genre
935+
instance.best_photo.blood_genre = blood_genre
936+
instance.best_photo.save()
892937
return instance
893938

894939
class Meta:
@@ -901,6 +946,7 @@ class Meta:
901946
"best_photo_uuid",
902947
"best_photo",
903948
"classification",
949+
"characteristics",
904950
"feedback",
905951
"type",
906952
"is_flagged",

api/tests/test_views.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from rest_framework_simplejwt.settings import api_settings
1717

1818
from tigacrafting.models import ExpertReportAnnotation, IdentificationTask, PhotoPrediction, FavoritedReports
19-
from tigaserver_app.models import TigaUser, Report, Device, MobileApp
19+
from tigaserver_app.models import TigaUser, Report, Device, MobileApp, Photo
2020

2121
from api.tests.clients import AppAPIClient
2222
from api.tests.integration.observations.factories import create_observation_object
@@ -843,6 +843,43 @@ def test_is_favourite_does_nothing_if_already_exists_FavoritedReports(self, api_
843843
user=annotation.user
844844
).exists()
845845

846+
@pytest.mark.parametrize(
847+
"sex, is_blood_fed, is_gravid, expected_genre_blood",
848+
[
849+
('male', False, False, Photo.BLOOD_GENRE_MALE),
850+
('male', False, True, Photo.BLOOD_GENRE_MALE),
851+
('male', True, False, Photo.BLOOD_GENRE_MALE),
852+
('male', True, True, Photo.BLOOD_GENRE_MALE),
853+
('female', False, False, Photo.BLOOD_GENRE_FEMALE),
854+
('female', False, True, Photo.BLOOD_GENRE_FEMALE_GRAVID),
855+
('female', True, False, Photo.BLOOD_GENRE_FEMALE_BLOOD_FED),
856+
('female', True, True, Photo.BLOOD_GENRE_FEMALE_GRAVID_BLOOD_FED),
857+
(None, False, False, Photo.BLOOD_GENRE_UNKNOWN),
858+
(None, False, True, Photo.BLOOD_GENRE_UNKNOWN),
859+
(None, True, False, Photo.BLOOD_GENRE_UNKNOWN),
860+
(None, True, True, Photo.BLOOD_GENRE_UNKNOWN),
861+
]
862+
)
863+
def test_characteristics_sets_Photo_blood_genre_field(self, api_client, endpoint, identification_task, common_post_data, with_add_permission, sex, is_blood_fed, is_gravid, expected_genre_blood):
864+
post_data = common_post_data
865+
post_data['best_photo_uuid'] = identification_task.photo.uuid
866+
post_data['characteristics'] = {
867+
'sex': sex,
868+
'is_blood_fed': is_blood_fed,
869+
'is_gravid': is_gravid
870+
}
871+
872+
response = api_client.post(
873+
endpoint,
874+
data=post_data,
875+
format='json'
876+
)
877+
assert response.status_code == status.HTTP_201_CREATED
878+
879+
annotation = ExpertReportAnnotation.objects.get(pk=response.data['id'])
880+
photo = annotation.best_photo
881+
assert photo.blood_genre == expected_genre_blood
882+
846883
@pytest.mark.parametrize(
847884
"pre_assign",
848885
[True, False]

tigaserver_app/models.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,12 +2983,19 @@ def wrapper(instance, filename):
29832983
return wrapper
29842984
'''
29852985

2986-
BLOOD_GENRE = (('male', 'Male'), ('female', 'Female'), ('fblood', 'Female blood'), ('fgravid', 'Female gravid'), ('fgblood', 'Female gravid + blood'), ('dk', 'Dont know') )
2987-
29882986
class Photo(models.Model):
29892987
"""
29902988
Photo uploaded by user.
29912989
"""
2990+
BLOOD_GENRE_MALE = 'male'
2991+
BLOOD_GENRE_FEMALE = 'female'
2992+
BLOOD_GENRE_FEMALE_BLOOD_FED = 'fblood'
2993+
BLOOD_GENRE_FEMALE_GRAVID = 'fgravid'
2994+
BLOOD_GENRE_FEMALE_GRAVID_BLOOD_FED = 'fgblood'
2995+
BLOOD_GENRE_UNKNOWN = 'dk'
2996+
2997+
BLOOD_GENRE = ((BLOOD_GENRE_MALE, 'Male'), (BLOOD_GENRE_FEMALE, 'Female'), (BLOOD_GENRE_FEMALE_BLOOD_FED, 'Female blood'), (BLOOD_GENRE_FEMALE_GRAVID, 'Female gravid'), (BLOOD_GENRE_FEMALE_GRAVID_BLOOD_FED, 'Female gravid + blood'), (BLOOD_GENRE_UNKNOWN, 'Dont know') )
2998+
29922999
photo = ProcessedImageField(
29933000
upload_to=make_image_uuid,
29943001
processors=[ResizeToFit(height=2160, upscale=False)],

0 commit comments

Comments
 (0)