Ever used django-reversion?
It's an extension to the Django web framework that provides version control for model instances.
Pretty great for time-traveling inside your records, but what if you need to display versions using
django-rest-framework API?
Here's a nice solution for this.
2021-07-29 update: I made a django-reversion-rest-framework package to help users to implement this. Check the documentation on pypy or in the GitHub repo.
Note: follow the official website for the installation and the integration of django-reversion in your project, otherwise future steps won't work.
Preparation
You might need to enable the ReversionMiddleware
for storing a version for each API change.
Follow the instructions here,
you should add 'reversion.middleware.RevisionMiddleware'
to your MIDDLEWARE
setting.
Serializers
Create two custom serializers for Version and Revision
# serializers.py
from rest_framework import serializers
from reversion.models import Revision, Version
class RevisionSerializer(serializers.ModelSerializer):
"""
you can use a custom user serializer here, if you omit this line the `user`
field will contain the user_id
"""
user = SimpleUserSerializer()
class Meta:
model = Revision
fields = ('date_created', 'user', 'comment')
class VersionSerializer(serializers.ModelSerializer):
revision = RevisionSerializer()
class Meta:
model = Version
fields = ('revision', 'field_dict',)
Views
Extend the ModelViewSet with a history
action
# views.py
from rest_framework import viewsets
from reversion.models import Version
from .serializers import VersionSerializer
class HistoryModelViewSet(viewsets.ModelViewSet):
@action(detail=True, methods=['GET'], name='Get History')
def history(self, request, pk=None):
object = self.get_object()
versions = Version.objects.get_for_object(object)
serializer = VersionSerializer(versions, many=True)
return Response(serializer.data)
Then use your custom HistoryModelViewSet
in place of the ModelViewSet
.
class MyModelViewSet(HistoryModelViewSet):
# ...
Hope this helps!