src/notes/api/fields/category.py
author ymh <ymh.work@gmail.com>
Fri, 30 Nov 2018 10:53:15 +0100
changeset 183 f8f3af9e5c83
parent 142 56850f5c73f6
permissions -rw-r--r--
Change the settings to avoid using Session authentication for rest framework as it raise exceptions in case client and backend are on the same domain On the filter, adapt to take into account new version of django_filters

'''
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')