- upgrade libraries
- python 3.7 compatibility
- First protocol management implementation
"""
Serializers for model core classes
"""
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
logger = logging.getLogger(__name__)
class DetailNoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = (
'ext_id', 'version', 'created', 'updated',
'plain', 'html', 'raw',
'categorization', 'margin_note', 'tc_start', 'tc_end'
)
read_only_fields = ('ext_id', 'version', 'created', 'updated')
class UpdateNoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = (
'ext_id', 'version', 'created', 'updated',
'plain', 'html', 'raw',
'categorization', 'margin_note', 'tc_start', 'tc_end'
)
read_only_fields = ('ext_id', 'version', 'created', 'updated', 'tc_start', 'tc_end')
class CreateNoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = (
'ext_id', 'version', 'created', 'updated',
'plain', 'html', 'raw',
'categorization', 'margin_note', 'tc_start', 'tc_end'
)
read_only_fields = ('version', 'created', 'updated')
def to_internal_value(self, data):
super_data = super().to_internal_value(data)
super_data['session'] = Session.objects.get(
ext_id=self.context['view'].kwargs['session_ext_id']
)
return super_data
class ListNoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = (
'ext_id', 'tc_start', 'tc_end'
)
read_only_fields = ('ext_id', )
class RootListNoteSerializer(serializers.ModelSerializer):
session = serializers.SlugRelatedField(read_only=True, slug_field='ext_id')
class Meta:
model = Note
fields = (
'ext_id', 'tc_start', 'tc_end', 'session'
)
read_only_fields = ('ext_id', )
class RootDetailNoteSerializer(serializers.ModelSerializer):
session = serializers.SlugRelatedField(read_only=True, slug_field='ext_id')
class Meta:
model = Note
fields = (
'ext_id', 'version', 'created', 'updated',
'plain', 'html', 'raw',
'categorization', 'margin_note', 'tc_start', 'tc_end',
'session'
)
read_only_fields = (
'ext_id', 'version', 'created', 'updated',
'plain', 'html', 'raw',
'categorization', 'margin_note', 'tc_start', 'tc_end',
'session'
)
class ListSessionSerializer(serializers.ModelSerializer):
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, read_only=True)
class Meta:
model = Session
fields = (
'ext_id', 'version', 'date', 'created', 'updated',
'owner', 'title', 'description', 'protocol', 'group'
)
read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group', 'protocol')
class DetailSessionSerializer(serializers.ModelSerializer):
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, read_only=True)
class Meta:
model = Session
fields = (
'ext_id', 'version', 'date', 'created', 'updated',
'owner', 'title', 'description', 'protocol', 'group',
'notes'
)
read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group', 'protocol')
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)
@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
fields = (
'ext_id', 'version', 'date', 'created', 'updated',
'owner', 'title', 'description', 'protocol', 'group'
)
read_only_fields = ('version', 'created', 'updated', 'owner')
@transaction.atomic()
def save(self,**kwargs):
return super().save(**kwargs)
def create(self, validated_data):
protocol = validated_data.pop('protocol')
if protocol is None or isinstance(protocol, dict):
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)
elif isinstance(protocol, str) and protocol.startswith(constants.PROTOCOL_URN_PREFIX):
validated_data['protocol'] = protocol
else:
raise Exception("Bad format for protocol")
return super().create(validated_data)