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

import logging

from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db import transaction
from notes import constants
from notes.api.fields.category import ProtocolField
from protocols.models import Protocol
from rest_auth.serializers import \
    UserDetailsSerializer as RestAuthUserDetailsSerializer
from rest_framework import serializers

logger = logging.getLogger(__name__)

User = get_user_model()

class GroupSerializer(serializers.ModelSerializer):
    owner = serializers.CharField(source='profile.owner.username', read_only=True)
    is_personal = serializers.BooleanField(source='profile.is_personal', read_only=True)
    description = serializers.CharField(source='profile.description')
    protocol = ProtocolField(read_only=True, source='profile.protocol')

    class Meta:
        model = Group
        fields = ['name', 'owner', 'is_personal', 'description', 'protocol']


class DetailGroupSerializer(GroupSerializer):
    users = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='username',
        source='user_set'
    )

    class Meta:
        model = Group
        fields = ['name', 'owner', 'description', 'users', 'is_personal', 'protocol']


class WriteGroupSerializer(serializers.ModelSerializer):
    '''
    Serializers for writing groups.
    '''

    description = serializers.CharField(source='profile.description', required=False)
    users = serializers.SlugRelatedField(
        many=True,
        slug_field='username',
        source='user_set',
        queryset=User.objects.all(),
        default=[]
    )
    protocol = ProtocolField(required=False, source='profile.protocol')

    class Meta:
        model = Group
        fields = ['name', 'description', 'users', 'protocol']


    def create(self, validated_data):
        profile_data = validated_data.pop('profile', None)

        group = super().create(validated_data)

        if profile_data is not None and profile_data.get('description', None) is not None:
            group.profile.description = profile_data.get('description')

        user = None
        request = self.context.get("request")
        if request and hasattr(request, "user"):
            user = request.user
            group.user_set.add(user)
            group.save()
        group.profile.owner = user

        new_protocol = Protocol.objects.create_from_default(
            "Protocol group %s"%validated_data.get('name', ''),
            "Protocol group %s"%validated_data.get('name', ''),
            validated_data.get('name', ''),
            None
        )
        group.profile.protocol = "%s%s.%s" % (constants.PROTOCOL_URN_PREFIX, new_protocol.ext_id, new_protocol.revisions.last().version)
        group.profile.save()

        return group

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile', None)
        group = super().update(instance, validated_data)

        logger.debug("WriteGroupSerializer.update %r", profile_data)
        if profile_data is not None and profile_data.get('description', None) is not None:
            group.profile.description = profile_data.get('description')
            group.profile.save()

        # check that owner is still in user list
        if group.profile.owner and group.profile.owner not in group.user_set.all():
            group.user_set.add(group.profile.owner)

        return group

    @transaction.atomic()
    def save(self, **kwargs):
        return super().save(**kwargs)


class UserDetailsSerializer(RestAuthUserDetailsSerializer):
    default_group = serializers.SlugRelatedField(read_only=True, slug_field='name', source='profile.default_group')

    class Meta(RestAuthUserDetailsSerializer.Meta):
        fields = ('pk', 'username', 'email', 'first_name', 'last_name', 'default_group')
        read_only_fields = ('email', 'default_group')