diff -r 80ce81208b08 -r 3051b847c124 server/python/django2/renkanmanager/serializers.py --- a/server/python/django2/renkanmanager/serializers.py Tue Jun 21 10:30:08 2016 +0200 +++ b/server/python/django2/renkanmanager/serializers.py Tue Jun 21 17:53:06 2016 +0200 @@ -3,8 +3,8 @@ from django.db import transaction from django.contrib.auth import get_user_model from django.conf import settings +from django.utils import six from django.core.exceptions import ValidationError -from django.utils import dateparse from renkanmanager import settings as renkan_settings from renkanmanager.models import Renkan, Workspace, Revision from rest_framework import serializers @@ -23,11 +23,14 @@ title = serializers.CharField(required=False) content = serializers.JSONField(required=False) creation_date = serializers.ReadOnlyField() - modification_date = serializers.SerializerMethodField("get_current_revision_modification_date") - create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating - validation_timestamp = serializers.CharField(write_only=True, required=False) # only used for updating is a content json is not provided + modification_date = serializers.SerializerMethodField() + + def __init__(self, instance=None, data=serializers.empty, **kwargs): - # ADD ERROR HANDLING + self.validation_timestamp = kwargs.pop('validation_timestamp', None) + super(RenkanSerializer, self).__init__(instance, data, **kwargs) + + def get_current_revision_last_updator(self, renkan): last_updator = renkan.current_revision.last_updated_by if last_updator: @@ -36,7 +39,7 @@ return '' - def get_current_revision_modification_date(self, renkan): + def get_modification_date(self, renkan): return renkan.current_revision.modification_date @transaction.atomic @@ -71,19 +74,12 @@ content = validated_data.get('content', '') if not content: content = renkan.current_revision.content - if not 'validation_timestamp' in validated_data: - raise serializers.ValidationError("No validation timestamp and no content json to extract it from") - validation_timestamp = validated_data.get('validation_timestamp') - else: - validation_timestamp = json.loads(content).get("updated", "") - if dateparse.parse_datetime(validation_timestamp) < renkan.current_revision.modification_date: - raise serializers.ValidationError("Provided timestamp is invalid") if title != json.loads(content).get("title", ""): content_dict = json.loads(content) content_dict["title"] = title content = json.dumps(content_dict) try: - renkan.save_renkan(updator=updator, timestamp=validation_timestamp, title=title, content=content, create_new_revision=create_new_revision) + renkan.save_renkan(updator=updator, timestamp=self.validation_timestamp, title=title, content=content, create_new_revision=create_new_revision) except ValidationError as ve: raise serializers.ValidationError(str(ve.args[0])) # FORCE Renkan reload. @@ -113,12 +109,16 @@ raise serializers.ValidationError("Content requires a 'views' entry") return value - def validate_validation_timestamp(self, value): - logger.debug("%r < %r", dateparse.parse_datetime(value).timestamp(), self.get_current_revision_modification_date(self.instance).timestamp()) + def validate(self, data): + if self.instance: + validation_timestamp = self.validation_timestamp or data.get('content', {}).get('updated') + if not validation_timestamp: + raise serializers.ValidationError("No validation timestamp and no content json to extract it from") + validation_timestamp = dateparse.parse_datetime(validation_timestamp) if isinstance(validation_timestamp, six.string_types) else validation_timestamp + if validation_timestamp != self.instance.current_revision.modification_date: + raise serializers.ValidationError("Invalid timestamp was provided") + return data - if self.instance and dateparse.parse_datetime(value) != self.get_current_revision_modification_date(self.instance): - raise serializers.ValidationError("Invalid timestamp was provided") - return value class RevisionSerializer(serializers.Serializer): id = serializers.ReadOnlyField(source="revision_guid")