mirror of
https://github.com/leaders-of-digital-9-task/backend.git
synced 2024-11-22 17:36:32 +03:00
275 lines
9.0 KiB
Python
275 lines
9.0 KiB
Python
from dicom.models import (
|
|
BaseShape,
|
|
Circle,
|
|
Coordinate,
|
|
Dicom,
|
|
FreeHand,
|
|
Layer,
|
|
Project,
|
|
Roi,
|
|
Ruler,
|
|
)
|
|
from dicom.services import create_coordinate
|
|
from drf_spectacular.utils import extend_schema_field
|
|
from rest_framework import serializers
|
|
from rest_framework.generics import get_object_or_404
|
|
|
|
|
|
class CoordinateSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Coordinate
|
|
fields = ["x", "y"]
|
|
|
|
|
|
class ListProjectSerializer(serializers.ModelSerializer):
|
|
url = serializers.HyperlinkedIdentityField(
|
|
view_name="get_update_delete_project", lookup_field="slug"
|
|
)
|
|
|
|
class Meta:
|
|
model = Project
|
|
fields = ["name", "pathology_type", "slug", "url", "created"]
|
|
extra_kwargs = {
|
|
"slug": {"read_only": True},
|
|
"created": {"read_only": True},
|
|
}
|
|
|
|
def create(self, validated_data):
|
|
return Project.objects.create(
|
|
user=self.context["request"].user,
|
|
name=validated_data["name"],
|
|
pathology_type=validated_data["pathology_type"],
|
|
)
|
|
|
|
|
|
class ListDicomSerializer(serializers.ModelSerializer):
|
|
url = serializers.HyperlinkedIdentityField(
|
|
view_name="get_update_delete_dicom", lookup_field="slug"
|
|
)
|
|
file = serializers.FileField()
|
|
|
|
class Meta:
|
|
model = Dicom
|
|
fields = ["file", "uploaded", "url"]
|
|
|
|
def create(self, validated_data):
|
|
return Dicom.objects.create(**validated_data, user=self.context["request"].user)
|
|
|
|
|
|
class ProjectSerializer(serializers.ModelSerializer):
|
|
files = ListDicomSerializer(many=True)
|
|
|
|
class Meta:
|
|
model = Project
|
|
fields = ["files", "slug", "created", "stl"]
|
|
|
|
|
|
class BaseShapeSerializer(serializers.Serializer):
|
|
model = BaseShape
|
|
|
|
type = serializers.ChoiceField(choices=["circle", "roi", "free_hand", "ruler"])
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
coordinates = CoordinateSerializer(many=True)
|
|
|
|
def create(self, validated_data):
|
|
if self.model.max_coordinates:
|
|
if len(validated_data["coordinates"]) > self.model.max_coordinates:
|
|
raise serializers.ValidationError
|
|
if self.model.min_coordinates:
|
|
if len(validated_data["coordinates"]) < self.model.min_coordinates:
|
|
raise serializers.ValidationError
|
|
dicom = get_object_or_404(
|
|
Dicom, slug=self.context["request"].parser_context["kwargs"]["slug"]
|
|
)
|
|
if validated_data["layer"]:
|
|
layer = get_object_or_404(Layer, slug=validated_data["layer"])
|
|
else:
|
|
layer = dicom.layers.filter(parent__isnull=True).first()
|
|
|
|
obj = self.model.objects.create(layer_fk=layer)
|
|
|
|
create_coordinate(validated_data["coordinates"], obj)
|
|
return obj
|
|
|
|
def update(self, obj, validated_data):
|
|
Coordinate.objects.filter(shape=obj).delete()
|
|
if self.model.max_coordinates:
|
|
if len(validated_data["coordinates"]) > self.model.max_coordinates:
|
|
raise serializers.ValidationError
|
|
if self.model.min_coordinates:
|
|
if len(validated_data["coordinates"]) < self.model.min_coordinates:
|
|
raise serializers.ValidationError
|
|
if validated_data["layer"]:
|
|
layer = get_object_or_404(Layer, slug=validated_data["layer"])
|
|
else:
|
|
layer = obj.dicom.layers.filter(parent__isnull=True).first()
|
|
if obj.layer_fk != layer:
|
|
obj.layer_fk = layer
|
|
obj.save()
|
|
create_coordinate(validated_data["coordinates"], obj)
|
|
return obj
|
|
|
|
|
|
class BaseShapeLayerSerializer(serializers.Serializer):
|
|
type = serializers.ChoiceField(choices=["circle", "roi", "free_hand", "ruler"])
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
radius = serializers.FloatField(required=False)
|
|
coordinates = CoordinateSerializer(many=True)
|
|
|
|
def validate_layer(self, val):
|
|
if val:
|
|
return get_object_or_404(Layer, slug=val).slug
|
|
return (
|
|
get_object_or_404(
|
|
Dicom,
|
|
slug=self.context["request"].parser_context["kwargs"]["dicom_slug"],
|
|
)
|
|
.layers.filter(parent__isnull=True)
|
|
.first()
|
|
.slug
|
|
)
|
|
|
|
|
|
class LayerChildSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Layer
|
|
fields = ["name", "slug"]
|
|
|
|
|
|
class LayerSerializer(serializers.ModelSerializer):
|
|
children = LayerChildSerializer(many=True, read_only=True)
|
|
parent = serializers.SlugField(max_length=8, allow_blank=True, write_only=True)
|
|
|
|
def validate_parent(self, val):
|
|
if val:
|
|
return get_object_or_404(Layer, slug=val)
|
|
return (
|
|
get_object_or_404(
|
|
Dicom,
|
|
slug=self.context["request"].parser_context["kwargs"]["dicom_slug"],
|
|
)
|
|
.layers.filter(parent__isnull=True)
|
|
.first()
|
|
)
|
|
|
|
class Meta:
|
|
model = Layer
|
|
fields = ["name", "slug", "children", "parent"]
|
|
extra_kwargs = {
|
|
"children": {"read_only": True},
|
|
"slug": {"read_only": True},
|
|
"parent": {"write_only": True},
|
|
}
|
|
|
|
def create(self, validated_data):
|
|
return Layer.objects.create(
|
|
name=validated_data["name"],
|
|
dicom=validated_data["parent"].dicom,
|
|
parent=validated_data["parent"],
|
|
)
|
|
|
|
|
|
class DicomSerializer(serializers.ModelSerializer):
|
|
file = serializers.FileField()
|
|
shapes = serializers.SerializerMethodField("get_dicom_shapes")
|
|
layers = serializers.SerializerMethodField("get_dicom_layers", read_only=True)
|
|
|
|
@extend_schema_field(field=BaseShapeSerializer(many=True))
|
|
def get_dicom_shapes(self, obj):
|
|
return [x.serialize_self() for x in obj.shapes.all()]
|
|
|
|
@extend_schema_field(field=LayerSerializer(many=True))
|
|
def get_dicom_layers(self, obj):
|
|
return obj.get_layers()
|
|
|
|
class Meta:
|
|
model = Dicom
|
|
fields = ["file", "uploaded", "shapes", "layers"]
|
|
|
|
|
|
class RoiSerializer(BaseShapeSerializer, serializers.ModelSerializer):
|
|
coordinates = CoordinateSerializer(many=True)
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
model = Roi
|
|
|
|
class Meta:
|
|
model = Roi
|
|
fields = ["id", "layer", "coordinates"]
|
|
extra_kwargs = {"id": {"read_only": True}}
|
|
|
|
|
|
class FreeHandSerializer(BaseShapeSerializer, serializers.ModelSerializer):
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
coordinates = CoordinateSerializer(many=True)
|
|
model = FreeHand
|
|
|
|
class Meta:
|
|
model = FreeHand
|
|
fields = ["id", "layer", "coordinates"]
|
|
extra_kwargs = {"id": {"read_only": True}}
|
|
|
|
|
|
class RulerSerializer(BaseShapeSerializer, serializers.ModelSerializer):
|
|
coordinates = CoordinateSerializer(many=True)
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
model = Ruler
|
|
|
|
class Meta:
|
|
model = FreeHand
|
|
fields = ["id", "layer", "coordinates"]
|
|
extra_kwargs = {"id": {"read_only": True}}
|
|
|
|
|
|
class CircleSerializer(serializers.ModelSerializer):
|
|
coordinates = CoordinateSerializer(many=True)
|
|
layer = serializers.SlugField(max_length=8, required=False, allow_blank=True)
|
|
|
|
class Meta:
|
|
model = Circle
|
|
fields = ["id", "layer", "radius", "coordinates"]
|
|
extra_kwargs = {"id": {"read_only": True}}
|
|
|
|
def create(self, validated_data):
|
|
if (
|
|
"coordinates" not in validated_data
|
|
and len(validated_data["coordinates"]) > 1
|
|
):
|
|
raise serializers.ValidationError
|
|
dicom = get_object_or_404(
|
|
Dicom, slug=self.context["request"].parser_context["kwargs"]["slug"]
|
|
)
|
|
if validated_data["layer"]:
|
|
layer = get_object_or_404(Layer, slug=validated_data["layer"])
|
|
else:
|
|
layer = dicom.layers.filter(parent__isnull=True).first()
|
|
circle = Circle.objects.create(
|
|
layer_fk=layer,
|
|
radius=validated_data["radius"],
|
|
)
|
|
|
|
create_coordinate(validated_data["coordinates"], circle)
|
|
return circle
|
|
|
|
def update(self, obj: Circle, validated_data):
|
|
Coordinate.objects.filter(shape=obj).delete()
|
|
create_coordinate(validated_data["coordinates"], obj)
|
|
if validated_data["layer"]:
|
|
layer = get_object_or_404(Layer, slug=validated_data["layer"])
|
|
else:
|
|
layer = obj.dicom.layers.filter(parent__isnull=True).first()
|
|
if "radius" in validated_data:
|
|
obj.radius = validated_data["radius"]
|
|
obj.layer_fk = layer
|
|
obj.save()
|
|
return obj
|
|
|
|
|
|
class SmartFileUploadSerializer(serializers.Serializer):
|
|
file = serializers.FileField()
|
|
|
|
|
|
class PatologyGenerateSerializer(serializers.Serializer):
|
|
project_slug = serializers.CharField()
|
|
points = serializers.ListField(child=CoordinateSerializer())
|
|
depth = serializers.ListField(child=serializers.IntegerField())
|