src/notes/api/serializers/auth.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

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