version.py 1.96 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
from django.contrib.contenttypes.models import ContentType
from django.core import serializers as djangoSerializers
from django.core.serializers.base import DeserializationError
from rest_framework import serializers
from reversion.models import Version

from backend_app.models.abstract.base import BaseModelSerializer, BaseModelViewSet


class VersionSerializer(BaseModelSerializer):
    """
    Custom serializer for the (reversion) version model
    """

    data = serializers.SerializerMethodField()

    def get_data(self, obj):
        """
        Serilizer for the data field
        """
        data = obj.serialized_data

        try:
            # We try to deserialize the version
            tmp = list(
                djangoSerializers.deserialize(obj.format, data, ignorenonexistent=True)
            )[0]
            # Version is valid,
            obj_serializer = tmp.object.get_serializer()
            new_context = dict(self.context)
            new_context["view"].action = "list"
            return obj_serializer(tmp.object, context=new_context).data
        except (DeserializationError, djangoSerializers.SerializerDoesNotExist):
            # The version is not valid regarding the model, we should delete it !
Florent Chehab's avatar
Florent Chehab committed
35
            # This might be due to an updated model structure at some point.
36
            obj.delete()
Florent Chehab's avatar
Florent Chehab committed
37 38
            # We take care of the nb_versions field update with signals.
            # So it will remain coherent.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
            return None

    class Meta:
        model = Version
        fields = ("data", "id")


class VersionViewSet(BaseModelViewSet):
    """
    Viewset for the versions
    """

    serializer_class = VersionSerializer

    def get_queryset(self):
        content_type_id = self.kwargs["content_type_id"]
        object_pk = self.kwargs["object_pk"]
        ct = ContentType.objects.get_for_id(content_type_id)
        model = ct.model_class()
        obj = model.objects.get(pk=object_pk)
        return Version.objects.get_for_object(obj)