src/notes/api/serializers/core.py
changeset 142 56850f5c73f6
parent 133 6f3078f7fd47
--- a/src/notes/api/serializers/core.py	Tue Jul 10 15:18:03 2018 +0200
+++ b/src/notes/api/serializers/core.py	Wed Jul 18 17:32:09 2018 +0200
@@ -4,11 +4,13 @@
 import logging
 
 from django.contrib.auth.models import Group
+from django.db import transaction
+from notes.api.fields.category import ProtocolField
+from notes import constants
+from notes.models import Note, Session
+from protocols.models import Protocol
 from rest_framework import serializers
 
-from notes.api.fields.category import ProtocolField
-from notes.models import Note, Session
-
 logger = logging.getLogger(__name__)
 
 
@@ -91,7 +93,7 @@
     owner = serializers.SlugRelatedField(
         read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
     group = serializers.SlugRelatedField(read_only=True, slug_field='name')
-    protocol = ProtocolField(required=False)
+    protocol = ProtocolField(required=False, read_only=True)
 
     class Meta:
         model = Session
@@ -107,7 +109,7 @@
     owner = serializers.SlugRelatedField(read_only=True, slug_field='username')
     notes = DetailNoteSerializer(many=True, read_only=True)
     group = serializers.SlugRelatedField(slug_field='name', read_only=True)
-    protocol = ProtocolField(required=False)
+    protocol = ProtocolField(required=False, read_only=True)
 
     class Meta:
         model = Session
@@ -118,12 +120,73 @@
         )
         read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group', 'protocol')
 
-class CreateSessionSerializer(serializers.ModelSerializer):
+class BaseSessionSerializer(serializers.ModelSerializer):
 
     owner = serializers.SlugRelatedField(
         read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
     group = serializers.SlugRelatedField(slug_field='name', queryset=Group.objects.all(), required=False, allow_null=True)
-    protocol = ProtocolField(required=False)
+
+    @transaction.atomic()
+    def save(self,**kwargs):
+        return super().save(**kwargs)
+
+    def create(self, validated_data):
+        return super().create(validated_data)
+
+    def update(self, instance, validated_data):
+        return super().update(instance, validated_data)
+
+    def validate(self, data):
+        data = super().validate(data)
+
+        group = data.get('group')
+        owner = data.get('owner')
+
+        if owner is None:
+            owner = self.fields['owner'].get_default()
+
+        if group is None:
+            if owner.profile and owner.profile.default_group:
+                group = owner.profile.default_group
+            if group is None and owner:
+                group = Group.objects.filter(profile__owner_personal=owner).first()
+
+        if group is None:
+            raise serializers.ValidationError("group field is required or default group or personal group could not be found for owner")
+        elif not owner in group.user_set.all():
+            raise serializers.ValidationError("Owner must be in group")
+
+        # Be careful: we update the data in the "validate". This is a side effect.
+        data['group'] = group
+        data['owner'] = owner
+
+        protocol = data.get('protocol')
+        if protocol is None:
+            data['protocol'] = group.profile.protocol
+        elif isinstance(protocol, dict) and 'owner' not in protocol:
+            data['protocol']['owner'] = group.name
+
+        return data
+
+class UpdateSessionSerializer(BaseSessionSerializer):
+
+    protocol = ProtocolField(required=False, allow_null=True, read_only=True)
+
+    class Meta:
+        model = Session
+        fields = (
+            'ext_id', 'version', 'date', 'created', 'updated',
+            'owner', 'title', 'description', 'protocol', 'group'
+        )
+        read_only_fields = ('ext_id', 'protocol', 'version', 'created', 'updated', 'owner')
+
+    @transaction.atomic()
+    def save(self,**kwargs):
+        return super().save(**kwargs)
+
+class CreateSessionSerializer(BaseSessionSerializer):
+
+    protocol = ProtocolField(required=False, allow_null=True)
 
     class Meta:
         model = Session
@@ -133,22 +196,21 @@
         )
         read_only_fields = ('version', 'created', 'updated', 'owner')
 
-    def validate(self, data):
-        data = super().validate(data)
+    @transaction.atomic()
+    def save(self,**kwargs):
+        return super().save(**kwargs)
 
-        group = data.get('group')
-        owner = data.get('owner')
+    def create(self, validated_data):
+        protocol = validated_data.pop('protocol')
+
+        if protocol is None or isinstance(protocol, dict):
 
-        if group is None:
-            if owner and owner.profile and owner.profile.default_group:
-                group = owner.profile.default_group
-            if group is None and owner:
-                group = Group.objects.filter(profile__owner_personal=owner).first()
+            protocol_revision = Protocol.objects.create_new_revision(protocol.get('id'), protocol, None)
+            validated_data['protocol'] = "%s%s.%s" % (constants.PROTOCOL_URN_PREFIX, protocol_revision.protocol.ext_id, protocol_revision.version)
 
-        if group is None:
-            raise serializers.ValidationError("group field is required or default group or personal group could not be found for owner")
-        elif not owner in group.user_set.all():
-            raise serializers.ValidationError("Owner must be in group")
+        elif isinstance(protocol, str) and protocol.startswith(constants.PROTOCOL_URN_PREFIX):
+            validated_data['protocol'] = protocol
+        else:
+            raise Exception("Bad format for protocol")
 
-        data['group'] = group
-        return data
+        return super().create(validated_data)