src/notes/api/fields/category.py
author ymh <ymh.work@gmail.com>
Wed, 18 Jul 2018 17:32:09 +0200
changeset 142 56850f5c73f6
parent 139 d3738ac909d8
permissions -rw-r--r--
- upgrade libraries - python 3.7 compatibility - First protocol management implementation

'''
field serializing and deserializing metacategorization protocols
'''
import json
import logging

from rest_framework import serializers

from notes import constants, settings
from protocols.models import Protocol, ProtocolRevision
from protocols.serializers import ProtocolRevisionSerializer

logger = logging.getLogger(__name__)

class ProtocolField(serializers.Field):

    default_error_messages = {
        'incorrect_format_str': 'Incorrect format. Expected `'+constants.PROTOCOL_URN_PREFIX+'<ext_id>.<version>`.',
        'protocol_unknown': 'Incorrect protocol, protocol {ext_id}, version {version} does not exists.',
        'incorrect_format': 'Incorrect format. Expected `'+constants.PROTOCOL_URN_PREFIX+'<ext_id>.<version>` or dict.'
    }

    def __init__(self, *args, **kwargs):
        logger.debug("ProtocolField.__init__ %r || %r", args, kwargs)
        super().__init__(*args, **kwargs)

    # def get_attribute(self, *args, **kwargs):
    #     logger.debug("ProtocolField.get_attribute %r || %r", args, kwargs)
    #     logger.debug("ProtocolField.get_attribute source %r", self.source)
    #     # We pass the object instance onto `to_representation`,
    #     # not just the field attribute.
    #     return kwargs.get('obj')

    def to_representation(self, value):
        if isinstance(value, str) and value.startswith(constants.PROTOCOL_URN_PREFIX) :
            protocol_id, protocol_version = value[len(constants.PROTOCOL_URN_PREFIX):].split('.')
            # TODO: treat error case, i.e. protocol is not found
            protocol_revision = ProtocolRevision.objects.get(protocol__ext_id=protocol_id, version=protocol_version)
            serializer = ProtocolRevisionSerializer(protocol_revision)
            return serializer.data
        elif isinstance(value, str):
            logger.debug("ProtocolField.to_representation value %r" % value)
            return json.loads(value)
        else:
            return value


    def to_internal_value(self, data):

        if isinstance(data, str) and data.startswith(constants.PROTOCOL_URN_PREFIX):
            try:
                ext_id, version = data[len(constants.PROTOCOL_URN_PREFIX):].split('.')
            except ValueError:
                self.fail('incorrect_format_str')
            if not ProtocolRevision.objects.filter(protocol__ext_id=ext_id, version=version).exists():
                self.fail('protocol_unknown', ext_id=ext_id, version=version)
            else:
                return data
        elif isinstance(data, dict):
            return data
        else:
            self.fail('incorrect_format')