server/python/django2/renkanmanager/serializers.py
changeset 610 b9edc1c1538a
parent 608 8fd40139827c
child 611 f0f07e2b841f
equal deleted inserted replaced
609:854a027c80ff 610:b9edc1c1538a
     1 import json
     1 import json, uuid, datetime, time
     2 import uuid
       
     3 
     2 
       
     3 from django.db import transaction
     4 from django.contrib.auth import get_user_model
     4 from django.contrib.auth import get_user_model
     5 from django.conf import settings
     5 from django.conf import settings
     6 from renkanmanager.models import Renkan, Workspace, Revision
     6 from renkanmanager.models import Renkan, Workspace, Revision
     7 from rest_framework import serializers
     7 from rest_framework import serializers
     8 
     8 
     9 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD)
     9 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD)
    10 
    10 
    11 class RenkanSerializer(serializers.Serializer):
    11 class RenkanSerializer(serializers.Serializer):
    12     id = serializers.ReadOnlyField(source="renkan_guid")
    12     id = serializers.ReadOnlyField(source="renkan_guid")
    13     current_revision_id = serializers.ReadOnlyField(source="current_revision_guid")
    13     current_revision_id = serializers.SlugRelatedField(source="current_revision", slug_field="revision_guid", read_only=True)
    14     workspace_id = serializers.CharField(source="workspace_guid", required=False)
    14     workspace_id = serializers.SlugRelatedField(source="workspace", slug_field="workspace_guid", queryset=Workspace.objects, required=False)
    15     source_revision_id = serializers.CharField(source="source_revision_guid", required=False)
    15     source_revision_id = serializers.SlugRelatedField(source="source_revision", slug_field="revision_guid", queryset=Revision.objects, required=False)
    16     revision_count = serializers.ReadOnlyField()
    16     revision_count = serializers.ReadOnlyField()
    17     created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
    17     created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
    18     last_updated_by = serializers.SerializerMethodField("get_current_revision_last_updator")
    18     last_updated_by = serializers.SerializerMethodField("get_current_revision_last_updator")
    19     title = serializers.CharField(required=False)
    19     title = serializers.CharField(required=False)
    20     content = serializers.JSONField(required=False)
    20     content = serializers.JSONField(required=False)
    21     creation_date = serializers.ReadOnlyField()
    21     creation_date = serializers.ReadOnlyField()
    22     modification_date = serializers.SerializerMethodField("get_current_revision_modification_date")
    22     modification_date = serializers.SerializerMethodField("get_current_revision_modification_date")
    23     create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating
    23     create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating
       
    24     validation_timestamp = serializers.CharField(write_only=True, required=False) # only used for updating is a content json is not provided
    24     
    25     
    25     # ADD ERROR HANDLING
    26     # ADD ERROR HANDLING
    26     def get_current_revision_last_updator(self, renkan):
    27     def get_current_revision_last_updator(self, renkan):
    27         current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid)
    28         return getattr(renkan.current_revision.last_updated_by, RENKAN_USER_DISPLAY_FIELD)
    28         return getattr(current_revision.last_updated_by, RENKAN_USER_DISPLAY_FIELD)
       
    29     
    29     
    30     
    30     
    31     def get_current_revision_modification_date(self, renkan):
    31     def get_current_revision_modification_date(self, renkan):
    32         current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid)
    32         return renkan.current_revision.modification_date
    33         return current_revision.modification_date
       
    34     
    33     
       
    34     @transaction.atomic
    35     def create(self, validated_data):
    35     def create(self, validated_data):
    36         """
    36         """
    37             Method to create a new Renkan (and its first revision)
    37             Method to create a new Renkan (and its first revision)
    38         """
    38         """
    39         creator = validated_data.get('creator')
    39         creator = validated_data.get('creator')
    40         initial_revision = Revision.objects.create(
    40         workspace_obj = validated_data.get('workspace', None)
    41             title = validated_data.get('title', 'Untitled renkan'),
    41         source_revision_obj = validated_data.get('source_revision', None)
    42             creator = creator,
    42         try:
    43             last_updated_by = creator
    43             return Renkan.objects.create_renkan(
    44         )
    44                 creator=creator,
    45         renkan = Renkan.objects.create(
    45                 title=validated_data.get('title', ''),
    46             current_revision_guid = initial_revision.revision_guid,
    46                 content=validated_data.get('content', ''),
    47             workspace_guid = validated_data.get('workspace_guid', ''),
    47                 workspace=workspace_obj,
    48             source_revision_guid = validated_data.get('source_revision_guid', ''),
    48                 source_revision=source_revision_obj
    49             creator = creator
    49             )
    50         )
    50         except ValidationError as ve:
    51         initial_revision.parent_renkan_guid = renkan.renkan_guid
    51             raise serializers.ValidationError(ve.args[0])
    52         initial_revision.content = validated_data.get('content', json.dumps(
       
    53             {
       
    54                 "id": str(renkan.renkan_guid),
       
    55                 "title": initial_revision.title,
       
    56                 "description": "",
       
    57                 "created": str(initial_revision.creation_date),
       
    58                 "updated": str(initial_revision.modification_date),
       
    59                 "edges": [],
       
    60                 "nodes": [],
       
    61                 "users": [],
       
    62                 "space_id": str(renkan.workspace_guid),
       
    63                 "views": []
       
    64             }
       
    65         ))
       
    66         initial_revision.save()
       
    67         renkan.save()
       
    68         return renkan
       
    69     
    52     
       
    53     @transaction.atomic
    70     def update(self, renkan, validated_data):
    54     def update(self, renkan, validated_data):
    71         """
    55         """
    72             Method to update a Renkan object. Creates a new revision if needed
    56             Method to update a Renkan object. Creates a new revision if needed
    73         """
    57         """
    74         updator = validated_data.get('updator')
    58         updator = validated_data.get('updator')
    75         current_revision = Revision.objects.get(revision_guid=renkan.current_revision_guid)  
    59         create_new_revision = validated_data.get("create_new_revision", False)
    76         if validated_data.get("create_new_revision", False):
    60         title = validated_data.get('title', renkan.current_revision.title)
    77             revision_to_update = Revision.objects.create(creator=updator)
    61         content = validated_data.get('content', '')
    78             revision_to_update.parent_renkan_guid = renkan.renkan_guid
    62         if not content:
    79             renkan.current_revision_guid = revision_to_update.revision_guid
    63             content = renkan.current_revision.content
       
    64             if not 'validation_timestamp' in validated_data:
       
    65                 raise serializers.ValidationError("No validation timestamp and no content json to extract it from")
       
    66             validation_timestamp = validated_data.get('validation_timestamp')
    80         else:
    67         else:
    81             revision_to_update = current_revision
    68             validation_timestamp = json.loads(content).get("updated", "")
    82         revision_to_update.title = validated_data.get('title', current_revision.title)
    69         if title != json.loads(content).get("title", ""):
    83         revision_to_update.content = validated_data.get('content', current_revision.content)
    70             content_dict = json.loads(content)
    84         revision_to_update.last_updated_by = updator
    71             content_dict["title"] = title
    85         revision_to_update.save()
    72             content = json.dumps(content_dict)
    86         if not updator.has_perm('view_revision', revision_to_update):
    73         try:
    87             assign_perm('view_revision', updator, revision_to_update)
    74             renkan.save_renkan(updator=updator, timestamp=validation_timestamp, title=title, content=content, create_new_revision=create_new_revision)
    88             assign_perm('delete_revision', updator, revision_to_update)
    75         except ValidationError as ve:
    89         renkan.save()
    76             raise serializers.ValidationError(ve.args[0])
    90         return renkan
    77         return renkan
    91     
    78     
    92     def validate_workspace_id(self, value):
    79     def validate_workspace_id(self, value):
    93         if self.instance is not None:
    80         if self.instance is not None:
    94             raise serializers.ValidationError("You cannot update workspace_guid")
    81             raise serializers.ValidationError("You cannot update workspace_guid")
    97     def validate_source_revision_id(self, value):
    84     def validate_source_revision_id(self, value):
    98         if self.instance is not None:
    85         if self.instance is not None:
    99             raise serializers.ValidationError("You cannot update source_revision_guid")
    86             raise serializers.ValidationError("You cannot update source_revision_guid")
   100         return value
    87         return value
   101     
    88     
   102     def validate_content(self, value):
    89     def validate_content(self, value):  
   103         
       
   104         try:
    90         try:
   105             json.loads(value)
    91             json.loads(value)
   106         except ValueError:
    92         except ValueError:
   107             raise serializers.ValidationError("Content format is not a JSON-serializable")
    93             raise serializers.ValidationError("Content format is not a JSON-serializable")
   108         loaded_json = json.loads(value)
    94         loaded_json = json.loads(value)
   117         return value
   103         return value
   118 
   104 
   119 
   105 
   120 class RevisionSerializer(serializers.Serializer):
   106 class RevisionSerializer(serializers.Serializer):
   121     id = serializers.ReadOnlyField(source="revision_guid")
   107     id = serializers.ReadOnlyField(source="revision_guid")
   122     parent_renkan_id = serializers.ReadOnlyField(source="parent_renkan_guid")
   108     parent_renkan_id = serializers.SlugRelatedField(source="parent_renkan", slug_field='renkan_guid', read_only=True)
   123     workspace_id = serializers.SerializerMethodField("get_related_workspace_guid")
   109     workspace_id = serializers.SerializerMethodField("get_related_workspace_guid")
   124     title = serializers.ReadOnlyField()
   110     title = serializers.ReadOnlyField()
   125     content = serializers.JSONField(read_only=True)
   111     content = serializers.JSONField(read_only=True)
   126     renkan_created_by = serializers.SerializerMethodField("get_related_renkan_creator")
   112     renkan_created_by = serializers.SerializerMethodField("get_related_renkan_creator")
   127     renkan_creation_date = serializers.SerializerMethodField("get_related_renkan_creation_date")
   113     renkan_creation_date = serializers.SerializerMethodField("get_related_renkan_creation_date")
   128     revision_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
   114     revision_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
   129     revision_last_updated_by = serializers.StringRelatedField(source="last_updated_by")
   115     revision_last_updated_by = serializers.SlugRelatedField(source="last_updated_by", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
   130     revision_modification_date = serializers.ReadOnlyField(source="modification_date")
   116     revision_modification_date = serializers.ReadOnlyField(source="modification_date")
   131     
   117     
   132     def get_related_workspace_guid(self, revision):
   118     def get_related_workspace_guid(self, revision):
   133         parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid)
   119         if revision.parent_renkan.workspace:
   134         return parent_renkan.workspace_guid
   120             return revision.parent_renkan.workspace.workspace_guid
       
   121         else:
       
   122             return ''
   135     
   123     
   136     def get_related_renkan_creator(self, revision):
   124     def get_related_renkan_creator(self, revision):
   137         parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid)
   125         return getattr(revision.parent_renkan.creator, RENKAN_USER_DISPLAY_FIELD)
   138         return getattr(parent_renkan.creator, RENKAN_USER_DISPLAY_FIELD)
       
   139     
   126     
   140     def get_related_renkan_creation_date(self, revision):
   127     def get_related_renkan_creation_date(self, revision):
   141         parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid)
   128         return revision.parent_renkan.creation_date
   142         return parent_renkan.creation_date
       
   143     
   129     
   144 
   130 
   145 class WorkspaceSerializer(serializers.Serializer):
   131 class WorkspaceSerializer(serializers.Serializer):
   146     id = serializers.ReadOnlyField(source="workspace_guid")
   132     id = serializers.ReadOnlyField(source="workspace_guid")
   147     workspace_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)
   133     workspace_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True)