1+ import reversion
12from cache_memoize import cache_memoize
23from django .core .exceptions import ObjectDoesNotExist
34from django .db .models import F , Q
78from rest_framework import pagination , serializers , status
89from rest_framework .generics import (
910 GenericAPIView ,
11+ ListAPIView ,
1012 ListCreateAPIView ,
1113 RetrieveAPIView ,
1214 RetrieveUpdateDestroyAPIView ,
1315)
1416from rest_framework .response import Response
17+ from reversion .models import Version
1518from swapper import load_model
1619
1720from openwisp_users .api .permissions import DjangoModelPermissions
2124 DeviceGroupListFilter ,
2225 DeviceListFilter ,
2326 DeviceListFilterBackend ,
27+ ReversionFilter ,
2428 TemplateListFilter ,
2529 VPNListFilter ,
2630)
2731from .serializers import (
2832 DeviceDetailSerializer ,
2933 DeviceGroupSerializer ,
3034 DeviceListSerializer ,
35+ ReversionSerializer ,
3136 TemplateSerializer ,
3237 VpnSerializer ,
3338)
@@ -277,6 +282,42 @@ def certificate_delete_invalidates_cache(cls, organization_id, common_name):
277282 cls .get_device_group .invalidate (cls , org_slug , common_name )
278283
279284
285+ class ReversionListView (ProtectedAPIMixin , ListAPIView ):
286+ serializer_class = ReversionSerializer
287+ queryset = Version .objects .select_related ('revision' ).order_by (
288+ '-revision__date_created'
289+ )
290+ filter_backends = [DjangoFilterBackend ]
291+ filterset_class = ReversionFilter
292+
293+
294+ class ReversionDetailView (ProtectedAPIMixin , RetrieveAPIView ):
295+ serializer_class = ReversionSerializer
296+ queryset = Version .objects .select_related ('revision' ).order_by (
297+ '-revision__date_created'
298+ )
299+ lookup_field = 'pk'
300+
301+
302+ class ReversionRestoreView (ProtectedAPIMixin , GenericAPIView ):
303+ serializer_class = serializers .Serializer
304+ queryset = Version .objects .select_related ('revision' ).order_by (
305+ '-revision__date_created'
306+ )
307+
308+ def post (self , request , * args , ** kwargs ):
309+ version = self .get_object ()
310+ with reversion .create_revision ():
311+ version .revert ()
312+ reversion .set_user (request .user )
313+ reversion .set_comment (
314+ f"Restored to previous revision: { version .revision_id } "
315+ )
316+
317+ serializer = ReversionSerializer (version , context = self .get_serializer_context ())
318+ return Response (serializer .data , status = status .HTTP_200_OK )
319+
320+
280321template_list = TemplateListCreateView .as_view ()
281322template_detail = TemplateDetailView .as_view ()
282323vpn_list = VpnListCreateView .as_view ()
@@ -288,3 +329,6 @@ def certificate_delete_invalidates_cache(cls, organization_id, common_name):
288329devicegroup_list = DeviceGroupListCreateView .as_view ()
289330devicegroup_detail = DeviceGroupDetailView .as_view ()
290331devicegroup_commonname = DeviceGroupCommonName .as_view ()
332+ reversion_list = ReversionListView .as_view ()
333+ reversion_detail = ReversionDetailView .as_view ()
334+ reversion_restore = ReversionRestoreView .as_view ()
0 commit comments