diff --git a/greg/api/serializers/consent.py b/greg/api/serializers/consent.py new file mode 100644 index 0000000000000000000000000000000000000000..2d1eadf6dad2599d1e188199d956d73060bb753b --- /dev/null +++ b/greg/api/serializers/consent.py @@ -0,0 +1,12 @@ +from rest_framework import serializers + +from greg.api.serializers.consent_type import ConsentTypeSerializerBrief +from greg.models import Consent + + +class ConsentSerializerBrief(serializers.ModelSerializer): + type = ConsentTypeSerializerBrief(read_only=True) + + class Meta: + model = Consent + fields = ["type", "consent_given_at"] diff --git a/greg/api/serializers/consent_type.py b/greg/api/serializers/consent_type.py index c3e626c22d4c625e78e92eed864a0be6a4d114d9..b7a5da36b436c671175dd9b636a6e49da86a46b0 100644 --- a/greg/api/serializers/consent_type.py +++ b/greg/api/serializers/consent_type.py @@ -7,3 +7,13 @@ class ConsentTypeSerializer(ModelSerializer): class Meta: model = ConsentType fields = "__all__" + + +class ConsentTypeSerializerBrief(ModelSerializer): + class Meta: + model = ConsentType + fields = [ + "identifier", + "valid_from", + "user_allowed_to_change", + ] diff --git a/greg/api/serializers/identity.py b/greg/api/serializers/identity.py new file mode 100644 index 0000000000000000000000000000000000000000..8cfd25538ddfee0fb033819807b73d76e3c596d2 --- /dev/null +++ b/greg/api/serializers/identity.py @@ -0,0 +1,26 @@ +from django.core.exceptions import ValidationError +from rest_framework import serializers + +from greg.models import Identity + + +class IdentitySerializer(serializers.ModelSerializer): + class Meta: + model = Identity + fields = "__all__" + + def is_duplicate(self, identity_type: str, value: str) -> bool: + # Guests may be verified using another unrecognised identification method, + # which the sponsor is required to elaborate in the value column. + # In this case we cannot assume the union of the identity type and + # the value to be unique across all records. + if identity_type == Identity.IdentityType.OTHER: + return False + + # If the type is a specific ID type, then duplicates are not expected + return Identity.objects.filter(type=identity_type).filter(value=value).exists() + + def validate(self, attrs): + if self.is_duplicate(attrs["type"], attrs["value"]): + raise ValidationError("Identity already exists") + return attrs diff --git a/greg/api/serializers/person.py b/greg/api/serializers/person.py index 16d362f73b8813d14638fbcb3ca0addce87e8bd4..f8fe4c9f45c4fe546c32bdb116b810e62c776cda 100644 --- a/greg/api/serializers/person.py +++ b/greg/api/serializers/person.py @@ -1,66 +1,9 @@ -from django.core.exceptions import ValidationError from rest_framework import serializers -from greg.models import Person, Role, RoleType, Identity, Consent, ConsentType - - -class RoleSerializer(serializers.ModelSerializer): - type = serializers.SlugRelatedField( - queryset=RoleType.objects.all(), slug_field="identifier" - ) - - class Meta: - model = Role - fields = [ - "id", - "start_date", - "end_date", - "sponsor", - "orgunit", - "created", - "updated", - "type", - ] - - -class IdentitySerializer(serializers.ModelSerializer): - class Meta: - model = Identity - fields = "__all__" - - def is_duplicate(self, identity_type: str, value: str) -> bool: - # Guests may be verified using another unrecognised identification method, - # which the sponsor is required to elaborate in the value column. - # In this case we cannot assume the union of the identity type and - # the value to be unique across all records. - if identity_type == Identity.IdentityType.OTHER: - return False - - # If the type is a specific ID type, then duplicates are not expected - return Identity.objects.filter(type=identity_type).filter(value=value).exists() - - def validate(self, attrs): - if self.is_duplicate(attrs["type"], attrs["value"]): - raise ValidationError("Identity already exists") - return attrs - - -class ConsentTypeSerializerBrief(serializers.ModelSerializer): - class Meta: - model = ConsentType - fields = [ - "identifier", - "valid_from", - "user_allowed_to_change", - ] - - -class ConsentSerializerBrief(serializers.ModelSerializer): - type = ConsentTypeSerializerBrief(read_only=True) - - class Meta: - model = Consent - fields = ["type", "consent_given_at"] +from greg.api.serializers.consent import ConsentSerializerBrief +from greg.api.serializers.identity import IdentitySerializer +from greg.api.serializers.role import RoleSerializer +from greg.models import Person class PersonSerializer(serializers.ModelSerializer): diff --git a/greg/api/serializers/role.py b/greg/api/serializers/role.py new file mode 100644 index 0000000000000000000000000000000000000000..31b2a43f187644fd83675982c5738567a3eea0ea --- /dev/null +++ b/greg/api/serializers/role.py @@ -0,0 +1,35 @@ +from rest_framework import serializers +from rest_framework.fields import IntegerField + +from greg.api.serializers.organizational_unit import OrganizationalUnitSerializer +from greg.models import Role, RoleType + + +class RoleSerializer(serializers.ModelSerializer): + type = serializers.SlugRelatedField( + queryset=RoleType.objects.all(), slug_field="identifier" + ) + orgunit = OrganizationalUnitSerializer() + + class Meta: + model = Role + fields = [ + "id", + "start_date", + "end_date", + "sponsor", + "orgunit", + "created", + "updated", + "type", + ] + + +class RoleWriteSerializer(RoleSerializer): + """ + Serializer for use with GET. + + When doing GET we want the complete orgunit object, not just the id. + """ + + orgunit = IntegerField(source="orgunit_id") # type: ignore diff --git a/greg/api/views/person.py b/greg/api/views/person.py index d5bed74610ea16fa32e2ba15a4f88b99c040370b..3214b41504d1023b9160fc29283233424f70081a 100644 --- a/greg/api/views/person.py +++ b/greg/api/views/person.py @@ -8,9 +8,9 @@ from greg.api.filters import PersonFilter, RoleFilter, IdentityFilter from greg.api.pagination import PrimaryKeyCursorPagination from greg.api.serializers.person import ( PersonSerializer, - RoleSerializer, IdentitySerializer, ) +from greg.api.serializers.role import RoleSerializer, RoleWriteSerializer from greg.models import Person, Role, Identity @@ -49,12 +49,21 @@ class RoleViewSet(viewsets.ModelViewSet): """Person role API""" queryset = Role.objects.all().order_by("id") - serializer_class = RoleSerializer pagination_class = PrimaryKeyCursorPagination filter_backends = (filters.DjangoFilterBackend,) filterset_class = RoleFilter lookup_field = "id" + def get_serializer_class(self): + """ + Fetch different serializer depending on http method. + + To return the complete orgunit object for GET we use a different serializer. + """ + if self.request.method in ("POST", "PATCH"): + return RoleWriteSerializer + return RoleSerializer + def get_queryset(self): qs = self.queryset if not self.kwargs: